Пример #1
0
void i2c_setbitrate(struct i2c_periph *periph, int bitrate)
{
  if (i2c_idle(periph))
  {
    if (periph == &i2c2)
    {
      I2C2_InitStruct.I2C_ClockSpeed = bitrate;
      I2C_Init(I2C2, i2c2.init_struct);
    }

#ifdef I2C_DEBUG_LED
        __disable_irq();

        LED2_ON();
        LED1_ON();
        LED2_OFF();
        LED1_OFF();
        LED2_ON();
        LED1_ON();
        LED2_OFF();
        LED1_OFF();

        __enable_irq();
#endif

   }
}
int main(void)
{
	char temp;

	LED1_INIT();
	LED2_INIT();
	uart_config_default_stdio();
	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
	sei();
	LED1_ON();
	LED2_ON();
	printf("\n\n********RFM22 Communication Test********\n");	
	LED1_ON();
	LED2_OFF();
	
	rfm22b_init();
	txtest_configure_radio();

	//====================//
	//Communications Test
	
	temp = rfm22b_read(DTYPE);
	temp = rfm22b_read(DVERS);
	temp = rfm22b_read(INTEN1);
	temp = rfm22b_read(INTEN2);
	temp = rfm22b_read(OMFC1);
	temp = rfm22b_read(OMFC2);
	
	LED1_OFF();
	LED2_ON();
	
	printf("*****************************************\n\n");
	txtest_send_current_packet();	// Send test packet	'0123456789:;<=>?"
	
	// This example allows you to enter a 16-byte packet to send
	printf("Entering TX Mode...Give me a 16-byte packet\n\n");
	
	LED1_OFF();
	LED2_OFF();
	txtest_fill_packet_from_uart();
	
	while(1)
	{
		txtest_send_current_packet();
		_delay_ms(1000);
	}
	return 0;
}
Пример #3
0
//*****************************************************************************
//
//! Control robot to go straight forward by following wall
//!
//!
//! \return true if left/right wall is detected
//!			false if no left/right wall is detected
//
static bool Forward()
{
	LED1_OFF();LED2_ON();LED3_OFF();
	//bluetooth_print("%d\r\n",avrSpeed);
	if ((!isWallLeft) || (!isWallRight))
	{
		forwardUpdateByWall();
		return true;
	}
	forwardUpdate();
	if (avrSpeed<AVG_SPEED_FWD_FAST-20)
		avrSpeed+=20;
	else if (avrSpeed>AVG_SPEED_FWD_FAST)
		avrSpeed=AVG_SPEED_FWD_FAST;

	if (isWallRight)
	{
		pid_wallfollow(leftError,rightError, avrSpeed,WALL_FOLLOW_RIGHT);
	}
	else if (isWallLeft)
	{
		pid_wallfollow(leftError,rightError, avrSpeed,WALL_FOLLOW_LEFT);
	}
	else
	{
		speed_set(MOTOR_RIGHT, avrSpeed);
		speed_set(MOTOR_LEFT, avrSpeed);
	}

	return false;
}
Пример #4
0
static inline void PPRZ_I2C_SEND_START(struct i2c_periph *periph)
{
  uint32_t i2c = (uint32_t) periph->reg_addr;

  // Reset the buffer pointer to the first byte
  periph->idx_buf = 0;

#ifdef I2C_DEBUG_LED
  LED_SHOW_ACTIVE_BITS(regs);

  LED2_ON();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED2_OFF();
#endif

  // Enable Error IRQ, Event IRQ but disable Buffer IRQ
  i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
  i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
  i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);

  // Issue a new start
  i2c_nack_current(i2c);
  i2c_disable_ack(i2c);
  i2c_clear_stop(i2c);
  i2c_peripheral_enable(i2c);
  i2c_send_start(i2c);
  periph->status = I2CStartRequested;

}
Пример #5
0
static inline void PPRZ_I2C_SEND_START(struct i2c_periph *periph)
{
  uint32_t i2c = (uint32_t) periph->reg_addr;

  // Reset the buffer pointer to the first byte
  periph->idx_buf = 0;

#ifdef I2C_DEBUG_LED
  LED_SHOW_ACTIVE_BITS(regs);

  LED2_ON();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED2_OFF();
#endif

  // Enable Error IRQ, Event IRQ but disable Buffer IRQ
  I2C_CR2(i2c) |= I2C_CR2_ITERREN;
  I2C_CR2(i2c) |= I2C_CR2_ITEVTEN;
  I2C_CR2(i2c) &= ~ I2C_CR2_ITBUFEN;

  // Issue a new start
  I2C_CR1(i2c) =  (I2C_CR1_START | I2C_CR1_PE);
  periph->status = I2CStartRequested;

}
Пример #6
0
static void vMain( void *pvParameters )
{
	buffer_t *buffer;
	vTaskDelay(500 / portTICK_RATE_MS );
	pause(200);
	debug_init(115200);
	pause(300);
	
	if(stack_start(NULL)==START_SUCCESS)
	{
		debug("Start Ok\r\n");
	}

	buffer = stack_buffer_get(0);
	if (buffer)
	{
		buffer->from = MODULE_NRP;
		buffer->to = MODULE_NRP;
		buffer->options.type = BUFFER_CONTROL;
		buffer_push_uint8(buffer, NRPC_RESET);
		stack_buffer_push(buffer);
	}
	LED2_ON();
	vTaskDelay(500 / portTICK_RATE_MS );	
	LED2_OFF();
	LED1_OFF();
	for( ;; )
	{
		//LED1_ON();
		vTaskDelay(5000 / portTICK_RATE_MS );
		//LED1_OFF();
	}
}
Пример #7
0
// *--------------------------------------------------------------------------------*
void BlinkUSBStatus(void){
    static WORD led_count=0;
    
    if(led_count == 0)led_count = 50000U;
    led_count--;

    #define mLED_Both_Off()         {LED1_OFF();LED2_OFF();}
    #define mLED_Both_On()          {LED1_ON();LED2_ON();}
    #define mLED_Only_1_On()        {LED1_ON();LED2_OFF();}
    #define mLED_Only_2_On()        {LED1_OFF();LED2_ON();}

    if(USBSuspendControl == 1){
        if(led_count==0){
            LED1_TOGGLE();
            if(LED1_READ()){
                LED2_ON();
            }else{
                LED2_OFF();
            }
        }
    }else{
        if(USBDeviceState == DETACHED_STATE){
            mLED_Both_Off();
        }else if(USBDeviceState == ATTACHED_STATE){
            mLED_Both_On();
        }else if(USBDeviceState == POWERED_STATE){
            mLED_Only_1_On();
        }else if(USBDeviceState == DEFAULT_STATE){
            mLED_Only_2_On();
        }else if(USBDeviceState == ADDRESS_STATE){
            if(led_count == 0){
                LED1_TOGGLE();
                LED2_OFF();
            }
        }else if(USBDeviceState == CONFIGURED_STATE){
            if(led_count==0){
                LED1_TOGGLE();
                if(LED1_READ()){
                    LED2_OFF();
                }else{
                    LED2_ON();
                }
            }
        }
    }

}
Пример #8
0
int main(void)
{
  unsigned char i;
  unsigned char ChkSum;
  //POWER ON indication: LED blink 3 times
  LED2_OUTPUT();
  LED2_OFF();
  MODULE_OFF(); //for reset
  for(i=0;i<3;i++){
    Delay_ms(200);
    LED2_ON();
    Delay_ms(200);
    LED2_OFF();
  }
  LED2_OFF();
  MODULE_ON(); //for reset
  Delay_ms(200);

  //Initialize command port
  RFXX_PORT_INIT();
  //Initialize RF12 chip
  RF12_INIT();
  //Init FIFO
  RFXX_WRT_CMD(0xCA81);
  while(1){
    //Enable FIFO
    RFXX_WRT_CMD(0xCA83);
    ChkSum=0;
    //Receive payload data
    for(i=0;i<16;i++){
      ChkSum+=RF12_RECV();
    }
    //Receive Check sum
    i=RF12_RECV();
    //Disable FIFO
    RFXX_WRT_CMD(0xCA81);
    //Package chkeck
    if(ChkSum==i){
      LED2_ON();
      Delay_ms(200);
      LED2_OFF();
    }
  }
}
Пример #9
0
void ButtonRightHandler(void)
{
	if (system_GetState() == SYSTEM_CALIB_SENSOR)
	{
		switch(IR_Calib_Step)
		{
			case 0:
				LED1_ON();
				LED2_OFF();
				LED3_OFF();
				IR_set_calib_value(IR_CALIB_BASE_LEFT);
				IR_set_calib_value(IR_CALIB_BASE_RIGHT);
				break;
			case 1:
				IR_set_calib_value(IR_CALIB_BASE_FRONT_LEFT);
				IR_set_calib_value(IR_CALIB_BASE_FRONT_RIGHT);
				LED1_OFF();
				LED2_ON();
				LED3_OFF();
				break;
			case 2:
				IR_set_calib_value(IR_CALIB_MAX_LEFT);
				LED1_ON();
				LED2_ON();
				LED3_OFF();
				break;
			case 3:
				IR_set_calib_value(IR_CALIB_MAX_RIGHT);
				LED1_OFF();
				LED2_OFF();
				LED3_ON();
				break;
			case 4:
				IR_set_calib_value(IR_CALIB_MAX_FRONT_LEFT);
				IR_set_calib_value(IR_CALIB_MAX_FRONT_RIGHT);
				LED1_ON();
				LED2_OFF();
				LED3_ON();
				break;
		}
		IR_Calib_Step++;
		IR_Calib_Step %= 4;
	}
}
Пример #10
0
static inline void LED_ERROR(uint8_t base, uint8_t nr)
{
  LED2_ON();
  for (int i=0;i<(base+nr);i++)
  {
    LED1_ON();
    LED1_OFF();
  }
  LED2_OFF();
}
Пример #11
0
static inline void PPRZ_I2C_SEND_STOP(uint32_t i2c)
{
  // Man: p722:  Stop generation after the current byte transfer or after the current Start condition is sent.
  i2c_send_stop(i2c);

#ifdef I2C_DEBUG_LED
  LED2_ON();
  LED1_ON();
  LED1_OFF();
  LED2_OFF();
#endif
}
Пример #12
0
static inline void PPRZ_I2C_SEND_STOP(I2C_TypeDef *regs)
{
  // Man: p722:  Stop generation after the current byte transfer or after the current Start condition is sent.
  regs->CR1 |= I2C_CR1_BIT_STOP;

#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
	LED1_OFF();
	LED2_OFF();
#endif
}
Пример #13
0
bool_t i2c_submit(struct i2c_periph* periph, struct i2c_transaction* t) {

  uint8_t temp;
  temp = periph->trans_insert_idx + 1;
  if (temp >= I2C_TRANSACTION_QUEUE_LEN) temp = 0;
  if (temp == periph->trans_extract_idx) {
    // queue full
    periph->errors->queue_full_cnt++;
    t->status = I2CTransFailed;
    return FALSE;
  }

  t->status = I2CTransPending;

  __disable_irq();
  /* put transacation in queue */
  periph->trans[periph->trans_insert_idx] = t;
  periph->trans_insert_idx = temp;

  /* if peripheral is idle, start the transaction */
  // if (PPRZ_I2C_IS_IDLE(p))
  if (periph->status == I2CIdle)
  {
    //if (i2c_idle(periph))
    {
#ifdef I2C_DEBUG_LED
#if USE_I2C1
      if (periph == &i2c1)
      {

      }
      else
#endif
#endif
      {
#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED2_OFF();
#endif
        PPRZ_I2C_SEND_START(periph);
      }
    }
  }
  /* else it will be started by the interrupt handler when the previous transactions completes */
  __enable_irq();

  return TRUE;
}
Пример #14
0
void system_Process_System_State(void)
{
	switch (system_GetState())
	{
		case SYSTEM_POWER_UP:
			break;
		case SYSTEM_INITIALIZE:
			break;
		case SYSTEM_CALIB_SENSOR:
			break;
		case SYSTEM_SAVE_CALIB_SENSOR:
			break;
		case SYSTEM_ESTIMATE_MOTOR_MODEL:
			ProcessSpeedControl();
			break;
		case SYSTEM_SAVE_MOTOR_MODEL:
			break;
		case SYSTEM_WAIT_TO_RUN:
			break;
		case SYSTEM_RUN_SOLVE_MAZE:
			pid_Wallfollow_process();
			ProcessSpeedControl();
			break;
		case SYSTEM_RUN_IMAGE_PROCESSING:
			LED1_ON();
			ProcessSpeedControl();
			break;
		case SYSTEM_ERROR:
			speed_Enable_Hbridge(false);
			system_Enable_BoostCircuit(false);
			IntMasterDisable();
			while (1)
			{
				LED1_ON();
				LED2_ON();
				LED3_ON();
				ROM_SysCtlDelay(ROM_SysCtlClockGet() / 3);
				LED1_OFF();
				LED2_OFF();
				LED3_OFF();
				ROM_SysCtlDelay(ROM_SysCtlClockGet() / 3);
			}
//			break;
	}
}
Пример #15
0
void ethernet_process(void) {


	if(linkstate == 0) {
		Dm9161       *pDm = &gDm9161;
		if( DM9161_GetLinkSpeed(pDm, 1) != 0 ) {

			TRACE_INFO("P: Link detected\n\r");
			linkstate=1;
			LED2_ON();
			// Auto Negotiate
			if (!DM9161_AutoNegotiate(pDm)) {

				TRACE_INFO("P: Auto Negotiate ERROR!\n\r");
				return;
			}
		}
	} else {


		uip_len = network_read();

		if(uip_len > 0) {

			if(BUF->type == htons(UIP_ETHTYPE_IP)){
				uip_arp_ipin();
				uip_input();
				if(uip_len > 0) {
					uip_arp_out();
					network_send();
				}

			} else if(BUF->type == htons(UIP_ETHTYPE_ARP)){

				uip_arp_arpin();
				if(uip_len > 0){
					network_send();
				}
			}
		}
	}

}
Пример #16
0
int main( void )
{
	LED_INIT();
	if (bus_init() == pdFALSE)
	{
		for (;;)
		{
			LED1_ON();
			LED2_OFF();
			LED1_OFF();
			LED2_ON();
		}
	}	
	
	xTaskCreate( vSensorTask, "Sens", configMINIMAL_STACK_SIZE + 100, NULL, (tskIDLE_PRIORITY + 2 ), NULL );
	vTaskStartScheduler();

	return 0;
}
Пример #17
0
static inline void PPRZ_I2C_SEND_START(struct i2c_periph *periph)
{
  I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr;

  periph->idx_buf = 0;

#ifdef I2C_DEBUG_LED
  LED_SHOW_ACTIVE_BITS(regs);

        LED2_ON();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
	LED2_OFF();

#endif

/*
  if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_STOP, regs->CR1 ) )
  {
    regs->CR1 &= ~ I2C_CR1_BIT_STOP;
  }
*/

  // Enable Error IRQ, Event IRQ but disable Buffer IRQ
  regs->CR2 |= I2C_CR2_BIT_ITERREN;
  regs->CR2 |= I2C_CR2_BIT_ITEVTEN;
  regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN;

  // Issue a new start
  regs->CR1 =  (I2C_CR1_BIT_START | I2C_CR1_BIT_PE);
  periph->status = I2CStartRequested;


#ifdef I2C_DEBUG_LED
  LED_SHOW_ACTIVE_BITS(regs);
#endif
}
Пример #18
0
void ButtonHandler(void)
{
	switch (system_GetState())
	{
		case SYSTEM_INITIALIZE:
			speed_Enable_Hbridge(false);
			system_SetState(SYSTEM_CALIB_SENSOR);
			IR_Calib_Step = 0;
			LED1_ON();
			LED2_ON();
			LED3_ON();
			break;
		case SYSTEM_CALIB_SENSOR:
			speed_Enable_Hbridge(false);
			system_SetState(SYSTEM_SAVE_CALIB_SENSOR);
		case SYSTEM_SAVE_CALIB_SENSOR:
			system_SetState(SYSTEM_ESTIMATE_MOTOR_MODEL);
			speed_Enable_Hbridge(true);
			speed_set(MOTOR_LEFT,500);
			speed_set(MOTOR_RIGHT, 500);
			break;
		case SYSTEM_ESTIMATE_MOTOR_MODEL:
//			system_SetState(SYSTEM_SAVE_MOTOR_MODEL);
			system_SetState(SYSTEM_WAIT_TO_RUN);
			speed_Enable_Hbridge(false);
			break;
		case SYSTEM_WAIT_TO_RUN:
			speed_Enable_Hbridge(true);
			system_SetState(SYSTEM_RUN_SOLVE_MAZE);
			break;
		case SYSTEM_RUN_SOLVE_MAZE:
		case SYSTEM_RUN_IMAGE_PROCESSING:
			system_SetState(SYSTEM_WAIT_TO_RUN);
			speed_Enable_Hbridge(false);
			break;
		default:
			break;
	}
}
Пример #19
0
static void led_thread_entry(void* parameter)
{
    int ledstate=0;
    while(1)
    {
//Led off
        ledstate=!ledstate;

        if(ledstate)
            LED2_ON();
        else
            LED2_OFF();
        if(test_ret>0)
        {
            rt_thread_delay(RT_TICK_PER_SECOND/4);
        }
        else
        {
            rt_thread_delay(RT_TICK_PER_SECOND*3);
        }
    }
}
Пример #20
0
int main(void)
{	
	unsigned char key;
	Sys_Clock_Init(); 		 
	SysTick_Configuration();//Sys定时器		
 	USART_Configuration();	//配置串口

	NVIC_Configuration(); 	//中断配置

//	sys_power_on();//开启系统电源
	LED_Init();		//指示灯
//	KEY_Init();		//按键

	USART1_Puts("this is a uart test!\n"); 

	
	CheckRTC();	   	//2.RTC
	LED2_OFF();

	while (1)
	{
		LED1_OFF();delay_nms(3000);
		LED1_ON();		delay_nms(100);
	  key=KEY_Scan();
		if(key==1)
		{LED2_ON();		}
// 		
// 		 if(mode==0)	  //显示时间
// 		 {
		 if(RTC_1S==TRUE)
			{
				RTC_1S=FALSE;
				UpdateRTC();
			}
// 		}

	}						                                                                         
}
Пример #21
0
void system_Process_System_State(void)
{
	switch (system_GetState())
	{
		case SYSTEM_POWER_UP:
			break;
		case SYSTEM_INITIALIZE:
			break;
		case SYSTEM_ESTIMATE_MOTOR_MODEL:
			break;
		case SYSTEM_SAVE_MOTOR_MODEL:
			break;
		case SYSTEM_WAIT_TO_RUN:
			break;
		case SYSTEM_RUN_BALANCE:
			loop();
			break;
		case SYSTEM_RUN_IMAGE_PROCESSING:
			LED1_ON();
			break;
		case SYSTEM_ERROR:
			speed_Enable_Hbridge(false);
			system_Enable_BoostCircuit(false);
			IntMasterDisable();
			while (1)
			{
				LED1_ON();
				LED2_ON();
				LED3_ON();
				ROM_SysCtlDelay(ROM_SysCtlClockGet() / 3);
				LED1_OFF();
				LED2_OFF();
				LED3_OFF();
				ROM_SysCtlDelay(ROM_SysCtlClockGet() / 3);
			}
	}
}
Пример #22
0
void i2c_setbitrate(struct i2c_periph *periph, int bitrate)
{
  // If NOT Busy
  if (i2c_idle(periph))
  {
    volatile int devider;
    volatile int risetime;

    uint32_t i2c = (uint32_t) periph->reg_addr;

    /*****************************************************
    Bitrate:

    -CR2 + CCR + TRISE registers
    -only change when PE=0

    e.g.

    10kHz:  36MHz + Standard 0x708 + 0x25
    70kHz:  36MHz + Standard 0x101 +
    400kHz: 36MHz + Fast 0x1E      + 0xb

    // 1) Program peripheral input clock CR2: to get correct timings
    // 2) Configure clock control registers
    // 3) Configure rise time register
    ******************************************************/

    if (bitrate < 3000)
      bitrate = 3000;

    // rcc_ppre1_frequency is normally configured to max: 36MHz on F1 and 42MHz on F4
    // in fast mode: 2counts low 1 count high -> / 3:
    // in standard mode: 1 count low, 1 count high -> /2:
    devider = (rcc_ppre1_frequency/2000) / (bitrate/1000);

    // never allow faster than 600kbps
    if (devider < 20)
      devider = 20;

    // no overflow either
    if (devider >=4095)
      devider = 4095;

    // risetime can be up to 1/6th of the period
    risetime = 1000000 / (bitrate/1000) / 6 / 28;

    if (risetime < 10)
      risetime = 10;

    // more will overflow the register: for more you should lower the FREQ
    if (risetime >=31)
      risetime = 31;

    // we do not expect an interrupt as the interface should have been idle, but just in case...
    __disable_irq(); // this code is in user space:

    // CCR can only be written when PE is disabled
    // p731 note 5
    i2c_peripheral_disable(i2c);

    // 1)
#ifdef STM32F1
    i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ);
#else // STM32F4
    i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ);
#endif
    // 2)
    //i2c_set_fast_mode(i2c);
    i2c_set_ccr(i2c, devider);
    // 3)
    i2c_set_trise(i2c, risetime);

    // Re-Enable
    i2c_peripheral_enable(i2c);

    __enable_irq();

#ifdef I2C_DEBUG_LED
    __disable_irq(); // this code is in user space:

    LED2_ON();
    LED1_ON();
    LED2_OFF();
    LED1_OFF();
    LED2_ON();
    LED1_ON();
    LED2_OFF();
    LED1_OFF();

    __enable_irq();
#endif

  }
}
Пример #23
0
static inline void i2c_irq(struct i2c_periph *periph)
{

  /*
	There are 7 possible reasons to get here:

	If IT_EV_FEN
	-------------------------

	We are always interested in all IT_EV_FEV: all are required.

	1) SB		// Start Condition Success in Master mode
	2) ADDR		// Address sent received Acknoledge
	[3 ADDR10]	// -- 10bit address stuff
	[4 STOPF]	// -- only for slaves: master has no stop interrupt
	5) BTF		// I2C has stopped working (it is waiting for new data, all buffers are tx_empty/rx_full)

	// Beware: using the buffered I2C has some interesting properties:
	  -in master receive mode: BTF only occurs after the 2nd received byte: after the first byte is received it is
           in RD but the I2C can still receive a second byte. Only when the 2nd byte is received while the RxNE is 1
	   then a BTF occurs (I2C can not continue receiving bytes or they will get lost). During BTF I2C is halted (SCL held low)
	  -in master transmitmode: when writing a byte to WD, you instantly get a new TxE interrupt while the first is not
	   transmitted yet. The byte was pushed to the I2C shift register and the buffer is ready for more. You can already
	   fill new data in the buffer while the first is still being transmitted for max performance transmission.

        // Beware: besides data buffering you can/must plan several consecutive actions. You can send 2 bytes to the buffer, ask for a stop and
           a new start in one go.

          -thanks to / because of this buffering and event sheduling there is not 1 interrupt per start / byte / stop
           This also means you must think more in advance and a transaction could be popped from the stack even before it is
           actually completely transmitted. But then you would not know the result yet so you have to keep it until the result
           is known.

	// Beware: the order in which Status is read determines how flags are cleared. You should not just read SR1 & SR2 every time

	If IT_EV_FEN AND IT_EV_BUF
	--------------------------

	Buffer event are not always wanted and are tipically switched on during longer data transfers. Make sure to turn off in time.

	6) RxNE
	7) TxE

	--------------------------------------------------------------------------------------------------
	// This driver uses only a subset of the pprz_i2c_states for several reasons:
	// -we have less interrupts than the I2CStatus states (for efficiency)
	// -STM32 has such a powerfull I2C engine with plenty of status register flags that
            only little extra status information needs to be stored.

       // Status is re-used (abused) to remember the last COMMAND THAT WAS SENT to the STM I2C hardware.

// TODO: check which are used
	enum I2CStatus {
	  I2CIdle,			// No more last command

	  I2CStartRequested,		// Last command was start
	  I2CRestartRequested,		// Last command was restart
	  I2CStopRequested,		// Very important to not send double stop conditions

	  I2CSendingByte,		// Some address/data operation

	  // Following are not used
	  I2CReadingByte,
	  I2CAddrWrSent,
	  I2CAddrRdSent,
	  I2CSendingLastByte,
	  I2CReadingLastByte,
	  I2CComplete,
	  I2CFailed
	};

	---------

	The STM waits indefinately (holding SCL low) for user interaction:
	a) after a master-start (waiting for address)
	b) after an address (waiting for data)
	   not during data sending when using buffered
	c) after the last byte is transmitted (waiting for either stop or restart)
	   not during data receiving when using buffered
	   not after the last byte is received

	-The STM I2C stalls indefinately when a stop condition was attempted that
	did not succeed. The BUSY flag remains on.
        -There is no STOP interrupt: use needs another way to finish.

   */


  ///////////////////////////////////////////////////////////////////////////////////
  // Reading the status:
  // - Caution: this clears several flags and can start transmissions etc...
  // - Certain flags like STOP / (N)ACK need to be guaranteed to be set before
  //   the transmission of the byte is finished. At higher clock rates that can be
  //   quite fast: so we allow no other interrupt to be triggered in between
  //   reading the status and setting all needed flags

  // Direct Access to the I2C Registers
  // Do not read SR2 as it might start the reading while an (n)ack bit might be needed first
  I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr;

#ifdef I2C_DEBUG_LED
  LED1_ON();
  LED1_OFF();
#endif


  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //
  //	TRANSACTION HANDLER

  enum STMI2CSubTransactionStatus ret = 0;

  ///////////////////////
  // Nothing Left To Do
  if (periph->trans_extract_idx == periph->trans_insert_idx)
  {
#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
	LED2_OFF();
	LED1_OFF();

    // no transaction and also an error?
    LED_SHOW_ACTIVE_BITS(regs);
#endif

    // If we still get an interrupt but there are no more things to do
    // (which can happen if an event was sheduled just before a bus error occurs)
    // then its easy: just stop: clear all interrupt generating bits

    // Count The Errors
    i2c_error(periph);

    // Clear Running Events
    stmi2c_clear_pending_interrupts(regs);

    // Mark this as a special error
    periph->errors->unexpected_event_cnt++;

    periph->status = I2CIdle;

    // There are no transactions anymore:
    // furtheron we need a transaction pointer: so we are not allowed to continue
    return;
  }

  struct i2c_transaction* trans = periph->trans[periph->trans_extract_idx];

  ///////////////////////////
  // If there was an error:
  if (( regs->SR1 & I2C_SR1_BITS_ERR ) != 0x0000)
  {

#ifdef I2C_DEBUG_LED
        LED1_ON();
        LED2_ON();
	LED1_OFF();
	LED2_OFF();

        LED_SHOW_ACTIVE_BITS(regs);
#endif

    // Set result in transaction
    trans->status = I2CTransFailed;

    // Prepare for next
    ret = STMI2C_SubTra_Ready;

    // Make sure a TxRx does not Restart
    trans->type = I2CTransRx;

/*
    // There are 2 types of errors: some need a STOP, some better do without: Following will not get an extra stop
    if (
           // Lost Arbitration
           (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_ERR_ARLO, regs->SR1 ) )
           // Buss Error When Master Only
        || ((BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_ERR_BUS,  regs->SR1 ) )  &&  (!BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_MSL,  regs->SR2 ) ))
        || (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_ERR_OVR,  regs->SR1 ) )
       )
    {
      ret = STMI2C_SubTra_Error;
    }
*/

    // Count The Errors
    i2c_error(periph);

    // Clear Running Events
    stmi2c_clear_pending_interrupts(regs);

  }


  ///////////////////////////
  // Normal Event:
  else
  {

    if (trans->type == I2CTransRx) // TxRx are converted to Rx after the Tx Part
    {
      switch (trans->len_r)
      {
        case 1:
          ret = stmi2c_read1(regs,trans);
          break;
        case 2:
          ret = stmi2c_read2(regs,trans);
          break;
        default:
          ret = stmi2c_readmany(regs,periph, trans);
          break;
      }
    }
    else // TxRx or Tx
    {
      ret = stmi2c_send(regs,periph,trans);
    }
  }

  /////////////////////////////////
  // Sub-transaction has finished
  if (ret != STMI2C_SubTra_Busy)
  {
    // If a restart is not needed
    if (trans->type != I2CTransTxRx)
    {
      // Ready, no stop condition set yet
      if (ret == STMI2C_SubTra_Ready)
      {

        // Program a stop
        PPRZ_I2C_SEND_STOP(regs);

        // Silent any BTF that would occur before STOP is executed
        regs->DR = 0x00;
      }

      // In case of unexpected condition: e.g. not slave, no event
      if (ret == STMI2C_SubTra_Error)
      {

        trans->status = I2CTransFailed;

    // Error
#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
	LED2_OFF();
	LED1_OFF();
#endif

        LED_SHOW_ACTIVE_BITS(regs);

        // Clear Running Events
        stmi2c_clear_pending_interrupts(regs);

      }


      // Jump to the next transaction
      periph->trans_extract_idx++;
      if (periph->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN)
        periph->trans_extract_idx = 0;

      // Tell everyone we are ready
      periph->status = I2CIdle;


      // if we have no more transaction to process, stop here
      if (periph->trans_extract_idx == periph->trans_insert_idx)
      {

#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
	LED2_OFF();
#endif
      }
      // if not, start next transaction
      else
      {
        // Restart transaction doing the Rx part now
// --- moved to idle function
        PPRZ_I2C_SEND_START(periph);
// ------
     }

    }
    // RxTx -> Restart and do Rx part
    else
    {
      trans->type = I2CTransRx;
      periph->status = I2CStartRequested;
      regs->CR1 |= I2C_CR1_BIT_START;

      // Silent any BTF that would occur before SB
      regs->DR = 0x00;
    }
  }

  return;
}
Пример #24
0
static inline enum STMI2CSubTransactionStatus stmi2c_readmany(I2C_TypeDef *regs, struct i2c_periph *periph, struct i2c_transaction *trans)
{
  uint16_t SR1 = regs->SR1;

  // Start Condition Was Just Generated
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_SB, SR1 ) )
  {
    regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN;
    // The first data byte will be acked in read many so the slave knows it should send more
    regs->CR1 &= ~ I2C_CR1_BIT_POS;
    regs->CR1 |= I2C_CR1_BIT_ACK;
    // Clear the SB flag
    regs->DR = trans->slave_addr | 0x01;
  }
  // Address Was Sent
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_ADDR, SR1) )
  {
    periph->idx_buf = 0;

    // Enable RXNE: receive an interrupt any time a byte is available
    // only enable if MORE than 3 bytes need to be read
    if (periph->idx_buf < (trans->len_r - 3))
    {
      regs->CR2 |= I2C_CR2_BIT_ITBUFEN;
    }

    // ACK is still on to get more DATA
    // Read SR2 to clear the ADDR (next byte will start arriving)
    uint16_t SR2 __attribute__ ((unused)) = regs->SR2;
  }
  // one or more bytes are available AND we were interested in Buffer interrupts
  else if ( (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_RXNE, SR1) ) && (BIT_X_IS_SET_IN_REG(I2C_CR2_BIT_ITBUFEN, regs->CR2))  )
  {
    // read byte until 3 bytes remain to be read (e.g. len_r = 6, -> idx=3 means idx 3,4,5 = 3 remain to be read
    if (periph->idx_buf < (trans->len_r - 3))
    {
      trans->buf[periph->idx_buf] = regs->DR;
      periph->idx_buf ++;
    }
    // from : 3bytes -> last byte: do nothing
    //
    // finally: this was the last byte
    else if (periph->idx_buf >= (trans->len_r - 1))
    {
      regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN;

      // Last Value
      trans->buf[periph->idx_buf] = regs->DR;
      periph->idx_buf ++;

      // We got all the results
      trans->status = I2CTransSuccess;

      return STMI2C_SubTra_Ready_StopRequested;
    }

    // Check for end of transaction: start waiting for BTF instead of RXNE
    if (periph->idx_buf < (trans->len_r - 3))
    {
      regs->CR2 |= I2C_CR2_BIT_ITBUFEN;
    }
    else // idx >= len-3: there are 3 bytes to be read
    {
      // We want to halt I2C to have sufficient time to clear ACK, so:
      // Stop listening to RXNE as it will be triggered infinitely since we did not empty the buffer
      // on the next (second in buffer) received byte BTF will be set (buffer full and I2C halted)
      regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN;
    }
  }
  // Buffer is full while this was not a RXNE interrupt
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_BTF, SR1) )
  {
    // Now the shift register and data register contain data(n-2) and data(n-1)
    // And I2C is halted so we have time

    // --- Make absolutely sure the next 2 I2C actions are performed with no delay
    __I2C_REG_CRITICAL_ZONE_START;

    // First we clear the ACK while the SCL is held low by BTF
    regs->CR1 &= ~ I2C_CR1_BIT_ACK;

    // Now that ACK is cleared we read one byte: instantly the last byte is being clocked in...
    trans->buf[periph->idx_buf] = regs->DR;
    periph->idx_buf ++;

    // Now the last byte is being clocked. Stop in MUST be set BEFORE the transfer of the last byte is complete
    PPRZ_I2C_SEND_STOP(regs);

    __I2C_REG_CRITICAL_ZONE_STOP;
    // --- end of critical zone -----------

    // read the byte2 we had in the buffer (BTF means 2 bytes available)
    trans->buf[periph->idx_buf] = regs->DR;
    periph->idx_buf ++;

    // Ask for an interrupt to read the last byte (which is normally still busy now)
    // The last byte will be received with RXNE
    regs->CR2 |= I2C_CR2_BIT_ITBUFEN;
  }
  else // Hardware error
  {
    // Error
#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
	LED2_OFF();
	LED1_OFF();
#endif
    return STMI2C_SubTra_Error;
  }

  return STMI2C_SubTra_Busy;
}
Пример #25
0
static inline void LED_SHOW_ACTIVE_BITS(I2C_TypeDef *regs)
{
  uint16_t CR1 = regs->CR1;
  uint16_t SR1 = regs->SR1;
  uint16_t SR2 = regs->SR2;
  // Note: reading SR1 and then SR2 will clear ADDR bits

  LED1_ON();

  // 1 Start
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_SB, SR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 2 Addr
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_ADDR, SR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 3 BTF
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_BTF, SR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 4 ERROR
  if (( SR1 & I2C_SR1_BITS_ERR ) != 0x0000)
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // Anything?
  if (( SR1 + SR2) != 0x0000)
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  LED1_OFF();


  LED1_ON();

  // 1 Start
  if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_START, CR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 2 Stop
  if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_STOP, CR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 3 Busy
  if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_BUSY, SR2 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 4 Tra
  if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_TRA, SR2 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 5 Master
  if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_MSL, SR2 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();
  LED1_OFF();

//#define I2C_DEBUG_LED_CONTROL
#ifdef I2C_DEBUG_LED_CONTROL


  LED1_ON();

  // 1 Anything CR?
  if (( CR1) != 0x0000)
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 2 PE
  if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_PE, CR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  // 3 SWRESET
  if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_SWRST, CR1 ) )
    LED2_ON();
  else
    LED2_OFF();
  LED2_OFF();

  LED1_OFF();
#endif

}
Пример #26
0
void i2c_event(void)
{
  static uint32_t cnt = 0;
  //I2C_TypeDef *regs;
  cnt++;
  if (cnt > 10000) cnt = 0;

#ifndef I2C_DEBUG_LED
#ifdef USE_I2C1
  if (i2c1.status == I2CIdle)
  {
    if (i2c_idle(&i2c1))
    {
      __disable_irq();
      // More work to do
      if (i2c1.trans_extract_idx != i2c1.trans_insert_idx)
      {
        // Restart transaction doing the Rx part now
        PPRZ_I2C_SEND_START(&i2c1);
      }
      __enable_irq();
    }
  }
#endif
#endif

#ifdef USE_I2C2

#ifdef I2C_DEBUG_LED
  if (cnt == 0)
  {
        __disable_irq();

        LED2_ON();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
        LED1_ON();
	LED1_OFF();
        if (i2c2.status == I2CIdle)
        {
          LED1_ON();
   	  LED1_OFF();
        }
        else if (i2c2.status == I2CStartRequested)
        {
          LED1_ON();
   	  LED1_OFF();
          LED1_ON();
   	  LED1_OFF();

        }
	LED2_OFF();

        //regs = (I2C_TypeDef *) i2c2.reg_addr;
        //LED_SHOW_ACTIVE_BITS(regs);

        __enable_irq();
  }
#endif


  //if (i2c2.status == I2CIdle)
  {
    //if (i2c_idle(&i2c2))
    {
      //__disable_irq();
      // More work to do
      //if (i2c2.trans_extract_idx != i2c2.trans_insert_idx)
      {
        // Restart transaction doing the Rx part now
        //PPRZ_I2C_SEND_START(&i2c2);
      }
      //__enable_irq();
    }
  }
#endif
}
Пример #27
0
/*****************************************************************************
*
* Cloud_Activate
*
*  \param  None
*
*  \return 1  - activation success
*          0  - activation failure
*
*  \brief  Called after Init has been run in the past, but maybe comms were
*          down and we have to keep trying
*
*****************************************************************************/
int
Cloud_Activate(void)
{
  int length;
  char DataLen[5];
  int newcik = 0;
//  int http_status = 0;
  char *cmp_ss = "Content-Length:";
  char *cmp = cmp_ss;
  DWORD serverip = 0;
  const unsigned char server[6] = SERVERIP;
  serverip = (server[3] << 24 & 0xff000000) | (server[2] << 16 & 0xff0000)
          | (server[1] << 8 & 0xff00) | (server[0] & 0xff);
  long w, r;
  char rev[300];
  unsigned char strLen, len;
  unsigned char cik_len_valid = 0;
  char *p;
  unsigned char crlf = 0;
  unsigned char ciklen = 0;
  int   time_out = 0;
  // Flag cloud_initialized is set by Cloud_Init()
  /*
  if (!cloud_initialized) {
    status_code = STATUS_INIT;
    return newcik;
  }
    */

  // clean the content of http header array

  if(status_code == STATUS_INIT||status_code == STATUS_END){

      //to launch a new HTTP POST operation, clean the content of header at first

      if (sock == INVALID_SOCKET)
      {
        sock = TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, HTTP_PORT, TCP_PURPOSE_TCP_CLIENT);

      // TCP_OPEN_RAM_HOST for using dns name as server name
     //  TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, server_port, TCP_PURPOSE_GENERIC_TCP_CLIENT);

       if (sock  == INVALID_SOCKET) {
             status_code = STATUS_INIT;
       //      LEDS_OFF();
        //     LEDS_ON();
            return 0;
         }
       status_code = STATUS_READY;

      }
      status_code == STATUS_READY;
  }
  else if(status_code == STATUS_READY)
  {
      // Get activation Serial Number
        DelayMs(20);
        w = TCPIsPutReady(sock);

        if(w<2000ul) {
           //   StackTask();
          //  TCPFlush((TCP_SOCKET)sock);
              return 0; }

  //      LED1_ON(); LED2_OFF();

       // if(w>2000ul) { LED2_ON(); LED1_OFF();}

     //   DelayMs(100);
        length = strlen(provision_info);

        IHMS_itoa(DataLen, length, 10); //make a string for length

        sendLine(sock, POSTDATA_LINE, "/activate.php");
        sendLine(sock, HOST_LINE, NULL);
        sendLine(sock, CONTENT_LINE, NULL);
     //   IHMS_SocketSend(sock, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);

        sendLine(sock, LENGTH_LINE, DataLen);

        IHMS_SocketSend(sock, provision_info, length);

        status_code = STATUS_RCV;
  }
  else if(status_code == STATUS_RCV)
  {
     DelayMs(20);
     r = TCPIsGetReady((TCP_SOCKET) sock);

     if(r<234u){ LED2_ON();  return 0;}
     // now read all data in RX buffer

    int count = 0;
    do
    {
        r = TCPGetArray((TCP_SOCKET)sock, (BYTE *)&rev[count], 300);
        count  = count + r;
        rev[count]=0;

        r = TCPIsGetReady((TCP_SOCKET) sock);

     }while(r>0u);

     rev[count] = 0 ;
      strLen = strlen(rev);
      len = strLen;
      p = rev;
      // Find 4 consecutive \r or \n - should be: \r\n\r\n
      while (0 < len && 4 > crlf)
      {
        if ('\r' == *p || '\n' == *p)
        {
          ++crlf;
        }
        else
        {
          crlf = 0;
          if (*cmp == *p)
          {
            // check the cik length from http response
            cmp++;
            if (cmp > cmp_ss + strlen(cmp_ss) - 1)
              cik_len_valid = 1;
          }
          else
            cmp = cmp_ss;
        }
        ++p;
        --len;
      }

     if(len>0)
     {
         LED1_ON();
         LED2_OFF();
     }



      // The body is the cik
        // TODO, be more robust - match Content-Length header value to CIK_LENGTH
      strncpy(CIK, p, CIK_LENGTH);

      CIK[40] = 0;
      newcik = 1;

    //IHMS_SocketClose(sock);

    TCPClose((TCP_SOCKET)sock);
    status_code = STATUS_END;
    sock = INVALID_SOCKET;

    return newcik;
  }

 // status_code = STATUS_INIT;
  return newcik;

}
Пример #28
0
static inline void i2c_irq(struct i2c_periph *periph)
{

  /*
    There are 7 possible event reasons to get here + all errors

    If IT_EV_FEN
    -------------------------

    We are always interested in all IT_EV_FEV: all are required.

    1) SB		// Start Condition Success in Master mode
    2) ADDR		// Address sent received Acknoledge
    [ADDR10]	// -- 10bit address stuff: not used
    [STOPF]		// -- only for slaves: master has no stop interrupt: not used
    3) BTF		// I2C has stopped working (it is waiting for new data, all buffers are tx_empty/rx_full)

    // Beware: using the buffered I2C has some interesting properties:
    - in master receive mode: BTF only occurs after the 2nd received byte: after the first byte is received it is
      in RD but the I2C can still receive a second byte. Only when the 2nd byte is received while the RxNE is 1
      then a BTF occurs (I2C can not continue receiving bytes or they will get lost). During BTF I2C is halted (SCL held low)
    - in master transmit mode: when writing a byte to WD, you instantly get a new TxE interrupt while the first is not
      transmitted yet. The byte was pushed to the I2C shift register and the buffer is ready for more. You can already
      fill new data in the buffer while the first is still being transmitted for max performance transmission.

    // Beware: besides data buffering you can/must plan several consecutive actions. You can send 2 bytes to the buffer, ask for a stop and
    a new start in one go.

    - thanks to / because of this buffering and event sheduling there is not 1 interrupt per start / byte / stop
      This also means you must think more in advance and a transaction could be popped from the transaction stack even before it's
      stop condition is actually generated.

    // Beware: the order in which Status (and other register) is read determines how flags are cleared.
    You should NOT simply read SR1 & SR2 every time

    If IT_EV_FEN AND IT_EV_BUF
    --------------------------

    Buffer event are not always wanted and are typically switched on during longer data transfers. Make sure to turn off in time.

    4) RxNE
    5) TxE

    --------------------------------------------------------------------------------------------------

    The STM waits indefinately (holding SCL low) for user interaction:
    a) after a master-start (waiting for address)
    b) after an address (waiting for data)
       not during data sending when using buffered
    c) after the last byte is transmitted (waiting for either stop or restart)
       not during data receiving when using buffered
       not after the last byte is received

    - The STM I2C stalls indefinately when a stop condition was attempted that
      did not succeed. The BUSY flag remains on.
    - There is no STOP interrupt.

    Caution Reading the status:
    - Caution: this clears several flags and can start transmissions etc...
    - Certain flags like STOP / (N)ACK need to be guaranteed to be set before
      the transmission of the byte is finished. At higher clock rates that can be
      quite fast: so we allow no other interrupt to be triggered in between
      reading the status and setting all needed flags

  */

  // Here we go ...

  // Apparently we got an I2C interrupt: EVT BUF or ERR

#ifdef I2C_DEBUG_LED
  // Notify ISR is triggered
  LED1_ON();
  LED1_OFF();
#endif

  // Save Some Direct Access to the I2C Registers ...
  uint32_t i2c = (uint32_t) periph->reg_addr;

  /////////////////////////////
  // Check if we were ready ...
  if (periph->trans_extract_idx == periph->trans_insert_idx)
  {
    // Nothing Left To Do

#ifdef I2C_DEBUG_LED
    LED2_ON();
    LED1_ON();
    LED2_OFF();
    LED1_OFF();

    // no transaction and also an error?
    LED_SHOW_ACTIVE_BITS(regs);
#endif

    // If we still get an interrupt but there are no more things to do
    // (which can happen if an event was sheduled just before a bus error occurs)
    // (or can happen if both error and event interrupts were called together [the 2nd will then get this error])

    // since there is nothing more to do: its easy: just stop: clear all interrupt generating bits

    // Count The Errors
    i2c_error(periph);

    // Clear Running Events
    stmi2c_clear_pending_interrupts(i2c);

    // Mark this as a special error
    periph->errors->last_unexpected_event++;

    // Document the current Status
    periph->status = I2CIdle;

    // There are no transactions anymore: return
    // further-on in this routine we need a transaction pointer: so we are not allowed to continue
    return;
  }

  // get the I2C transaction we were working on ...

  enum STMI2CSubTransactionStatus ret = 0;
  struct i2c_transaction* trans = periph->trans[periph->trans_extract_idx];

  ///////////////////////////
  // If there was an error:
  if (( I2C_SR1(i2c) & I2C_SR1_ERR_MASK ) != 0x0000)
  {

#ifdef I2C_DEBUG_LED
    LED1_ON();
    LED2_ON();
    LED1_OFF();
    LED2_OFF();

    LED_SHOW_ACTIVE_BITS(regs);
#endif

    // Notify everyone about the error ...

    // Set result in transaction
    trans->status = I2CTransFailed;

    // Document the current Status
    periph->status = I2CFailed;

    // Make sure a TxRx does not Restart
    trans->type = I2CTransRx;

    // Count The Errors
    i2c_error(periph);

    // Clear Running Events
    stmi2c_clear_pending_interrupts(i2c);

    // Now continue as if everything was normal from now on
    ret = STMI2C_SubTra_Ready;

  }

  ///////////////////////////
  // Normal Event:
  else
  {

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //	SUB-TRANSACTION HANDLER

    if (trans->type == I2CTransRx) // TxRx are converted to Rx after the Tx Part
    {
      switch (trans->len_r)
      {
      case 1:
        ret = stmi2c_read1(i2c,periph,trans);
        break;
      case 2:
        ret = stmi2c_read2(i2c,periph,trans);
        break;
      default:
        ret = stmi2c_readmany(i2c,periph,trans);
        break;
      }
    }
    else // TxRx or Tx
    {
      ret = stmi2c_send(i2c,periph,trans);
    }
  }

  /////////////////////////////////
  // Sub-transaction has finished
  if (ret != STMI2C_SubTra_Busy)
  {
    // Ready or SubTraError
    // -ready: with or without stop already asked

    // In case of unexpected event condition during subtransaction handling:
    if (ret == STMI2C_SubTra_Error)
    {
      // Tell everyone about the subtransaction error:
      // this is the previously called SPURRIOUS INTERRUPT
      periph->status = I2CFailed;
      trans->type = I2CTransRx;		// Avoid possible restart
      trans->status = I2CTransFailed;	// Notify Ready
      periph->errors->unexpected_event_cnt++;

      // Error
#ifdef I2C_DEBUG_LED
      LED2_ON();
      LED1_ON();
      LED2_OFF();
      LED1_OFF();

      LED_SHOW_ACTIVE_BITS(regs);
#endif

      // Clear Running Events
      stmi2c_clear_pending_interrupts(i2c);
    }

    // RxTx -> Restart and do Rx part
    if (trans->type == I2CTransTxRx)
    {
      trans->type = I2CTransRx;
      periph->status = I2CStartRequested;
      i2c_send_start(i2c);

      // Silent any BTF that would occur before SB
      i2c_send_data(i2c, 0x00);
    }
    // If a restart is not needed: Rx part or Tx-only
    else
    {
      // Ready, no stop condition set yet
      if (ret == STMI2C_SubTra_Ready)
      {

        // Program a stop
        PPRZ_I2C_SEND_STOP(i2c);

        // Silent any BTF that would occur before STOP is executed
        i2c_send_data(i2c, 0x00);
      }

      // Jump to the next transaction
      periph->trans_extract_idx++;
      if (periph->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN)
        periph->trans_extract_idx = 0;

      // Tell everyone we are ready
      periph->status = I2CIdle;


      // if we have no more transaction to process, stop here
      if (periph->trans_extract_idx == periph->trans_insert_idx)
      {

        periph->watchdog = -1; // stop watchdog
#ifdef I2C_DEBUG_LED
        LED2_ON();
        LED1_ON();
        LED1_OFF();
        LED1_ON();
        LED1_OFF();
        LED2_OFF();
#endif
      }
      // if not, start next transaction
      else
      {
        // Restart transaction doing the Rx part now
        // --- moved to idle function
        PPRZ_I2C_SEND_START(periph);
        // ------
      }
    }
  }

  return;
}
Пример #29
0
/*****************************************************************************
*
* Cloud_GetCmd
*
*  \param  pbuf - string buffer containing data to be sent
*          bufsize - number of bytes to send
*
*  \return 1 success; 0 failure
*
*  \brief  Writes data to Exosite cloud
*
*****************************************************************************/
int
Cloud_GetCmd()
{
  int length;
  char DataLen[10];
//  int http_status = 0;
  char *cmp_ss = "Content-Length:";
  char *cmp = cmp_ss;
  DWORD serverip = 0;
  const unsigned char server[6] = SERVERIP ;
  serverip = (server[3] << 24 & 0xff000000) | (server[2] << 16 & 0xff0000)
          | (server[1] << 8 & 0xff00) | (server[0] & 0xff);
  long w, r;
  char rev[300];
  unsigned char len;
  char *p;
  unsigned char crlf = 0;
  int  time_out = 0;
  int tx_buff_size = 250;

  int  tmp_len =0 ;

  if(status_code == STATUS_INIT||status_code == STATUS_END){

      if (sock == INVALID_SOCKET)
      {
        sock = TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, HTTP_PORT, TCP_PURPOSE_TCP_CLIENT);

      // TCP_OPEN_RAM_HOST for using dns name as server name
     //  TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, server_port, TCP_PURPOSE_GENERIC_TCP_CLIENT);

       if (sock  == INVALID_SOCKET) {
             status_code = STATUS_INIT;
       //      LEDS_OFF();
        //     LEDS_ON();
            return 0;
         }
       status_code = STATUS_READY;

      }
      else  status_code == STATUS_READY;
  }
  else if(status_code == STATUS_READY)
  {
       if(sent_header) DelayMs(20);
        w = TCPIsPutReady(sock);

       if(w<=250ul) {
              return 0; }

       if(sent_header){

             memset(header, 0, sizeof(header));
             length = PostHeaderGenerate("/sendcmd.php", command, 0, 0);
             remain_count =0 ;
             sent_header = FALSE;
             sent_count = 0;
       }
    //    LED2_ON(); LED1_OFF();

       int send_len = strlen(&header[remain_count]);

   //   LED2_ON(); LED1_OFF();
      //if(send_len > 254)  {LED2_ON(); LED1_OFF()};
      /*  The max size of sliding window for TCP packet is 254? after testing.
       *  Don't know the reason, but if we set the number of sending data to 250,
       * the program works fine.
       *
       */
      tmp_len = send_len>250? 250:send_len;
  //    int tmp_len = IHMS_SocketSend(sock, &header[sent_count], send_len );

      tmp_len = TCPPutArray(sock, (BYTE *) &header[remain_count], tmp_len);

      TCPFlush((TCP_SOCKET)sock);

      LED2_ON(); LED1_OFF();

     if(tmp_len<send_len)
     {
         remain_count += tmp_len;
         return 0;
     }
     memset(header, 0, sizeof(header));
     sent_count = 0;
     remain_count = 0;
     status_code = STATUS_RCV;

  }
   else if(status_code == STATUS_RCV)
  {
     DelayMs(20);
     r = TCPIsGetReady((TCP_SOCKET) sock);

     if(r<200u){ LED2_ON();  return 0;}
     // now read all data in RX buffer

    int count = 0;
    do
    {
        r = TCPGetArray((TCP_SOCKET)sock, (BYTE *)&rev[count], 300);
        count  = count + r;
        rev[count]=0;

        r = TCPIsGetReady((TCP_SOCKET) sock);

     }while(r>0u);

    rev[count] = 0 ;

    TCPClose((TCP_SOCKET)sock);
    status_code = STATUS_END;
    sock = INVALID_SOCKET;
    status_code = STATUS_END;

    sent_header = TRUE;
    //now it's time to read time

    command = GetServerCmd(rev, "cmd=");
    cmd_no = GetServerCmd(rev, "no=");

    return 1;

  }

  return 0;
}
Пример #30
0
//*****************************************************************************
//
//! Control two motor to make robot turn back 180 degree.
//!
//! \param fwdPulse is the distance robot will go straight before turn right
//!, the robot will stand between the next cell of maze.
//! \param avrSpeedLeft is the speed of left motor.
//! \param avrSpeedRight is the speed of left motor.
//! \param NumPulse is the total pulse of two encoder after turn
//! \param resetEnc is the reset value for encoder after turning back
//! \return true if finish
//!			false if not
//
static bool TurnBack(int fwdPulse, int avrSpeedLeft,int avrSpeedRight,int turnPulse,
		int resetEnc)
{
	LED1_ON();LED2_ON();LED3_ON();
	switch (CtrlStep)
	{
	case 1:
	{
		posLeftTmp = qei_getPosLeft();
		avrSpeedTmp = avrSpeed;
		CtrlStep++;
	}
	case 2://go forward a litte bit
	{

		if (abs(qei_getPosLeft()-posLeftTmp)<fwdPulse)
		{
			avrSpeed = ((abs(fwdPulse + posLeftTmp - qei_getPosLeft()) / (fwdPulse / avrSpeedTmp)) / 2)
					+ (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2;
			if (isWallRight)
				pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_RIGHT);
			else if (isWallLeft)
				pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_LEFT);
			else
			{
				speed_set(MOTOR_RIGHT, avrSpeed);
				speed_set(MOTOR_LEFT, avrSpeed);
			}
		}
		else
		{
			pid_reset(&pid_wall_left);
			pid_reset(&pid_wall_right);
			forwardUpdate();
			CtrlStep++;
			avrSpeed = avrSpeedTmp;
		}
		break;
	}
	case 3:
		posLeftTmp=qei_getPosLeft();
		posRightTmp=qei_getPosRight();
		CtrlStep++;
	case 4://turing 90 degree
	{
#ifdef TEST_TURNBACK_FWD
		speed_Enable_Hbridge(false);
#endif
		if ((abs(qei_getPosLeft()-posLeftTmp)+abs(qei_getPosRight()-posRightTmp))<turnPulse)
		{
			speed_set(MOTOR_RIGHT, avrSpeedRight);
			speed_set(MOTOR_LEFT, avrSpeedLeft);
		}
		else
		{
			currentDir=(currentDir+3)%4;
			CtrlStep++;
		}
		break;
	}
	case 5:
		posLeftTmp=qei_getPosLeft();
		posRightTmp=qei_getPosRight();
		CtrlStep++;
	case 6://turning another 90 degree
	{
#ifdef TEST_TURNBACK_TURN1
		speed_Enable_Hbridge(false);
#endif

		if ((abs(qei_getPosLeft()-posLeftTmp)+abs(qei_getPosRight()-posRightTmp))<turnPulse)
		{
			speed_set(MOTOR_RIGHT, -avrSpeedLeft);
			speed_set(MOTOR_LEFT, -avrSpeedRight);
		}
		else
		{
#ifdef TEST_TURNBACK_TURN2
		speed_Enable_Hbridge(false);
#endif
			currentDir=(currentDir+3)%4;
			clearPosition();
			qei_setPosLeft(resetEnc);
			qei_setPosRight(resetEnc);
			forwardUpdate();
			CtrlStep=1;
			return true;
		}
		break;
	}
	}
	return false;
}