ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
21 июля
36571
Romario (02.08.2005 21:04, просмотров: 1576)
не совсем по ARM, но работа с UART_TX и сигналом CTS от приёмника. Кому НЕ __лениво__ посмотрите прогу (много внутри) сбацал программку с 16C550 филипсовского UART с реакцией на CTS суть такова, из main передача идет с помощью GSMU__TxData(...) в HW_Uart1_Irq крутится основной цикл на передачу обрабатывая сигнал CTS. строчки помеченные "???" хочется вообще закоментарить. вопрос: все ли продумал и не будет ли "мертвых ситуаций"
#define TX_BUF_SZ 512
#define RX_BUF_SZ 512

static u8_t   u1TxBuf[TX_BUF_SZ];
static u32_t  u1TxWrPtr;
static u32_t  u1TxRdPtr;
static vu32_t u1TxSt   ;

static u8_t   u1RxBuf[RX_BUF_SZ];
static u32_t  u1RxWrPtr;
static u32_t  u1RxRdPtr;

#define TX_NO_DATA  BIN8(00000001)
#define TX_CTS_SET  BIN8(00000010)
#define TX_CUR_TX   BIN8(00000100)

/******************************************************************************
 * DESCRIPTION:
 * 
 *****************************************************************************/
u16_t GSMU__GetRxFillSz(void) {
 REG_t s32_t d = u1RxWrPtr - u1RxRdPtr;

   if (d < 0) {
       d += RX_BUF_SZ;
   }
   return d;
}

/******************************************************************************
 * DESCRIPTION:
 * 
 *****************************************************************************/
vu32_t imU1MSR;

__irq void HW_Uart1_Irq(void) {
  REG_t u32_t lw      ;
  REG_t u32_t TxSt = 0;
  REG_t u32_t run     ;  
  
/*******************************/
/*******************************/
/*******************************/
           lw = U1IIR;
    switch(lw & 0x0F) {
      ///////////////////////////////////
      ///// Rx Line Status / Error //////
      ///////////////////////////////////      
      case BIN(0110): 
           lw = U1LSR;   
           break;     

      ///////////////////////////////////
      //////  Rx Data Available /////////
      ///////////////////////////////////      
      case BIN(0100):    
                   lw = u1RxWrPtr;
           u1RxBuf[lw] = U1RBR;
           if   (++lw >= RX_BUF_SZ) {
                   lw  = 0;
           }
           u1RxWrPtr = lw;
           break;     
      ///////////////////////////////////
      /// Character Timeout Indication //
      ///////////////////////////////////
      case BIN(1100):
           break;     
      ///////////////////////////////////
      ////////////  THRE  ///////////////
      ///////////////////////////////////      
      case BIN(0010):
      	   TxSt = BIN(001);
           break;     
      ///////////////////////////////////
      /////////  Modem Status  //////////
      ///////////////////////////////////      
      case BIN(0000):    
               lw = U1MSR;
           if (lw & 1) {
             TxSt = BIN(100);
           }
           imU1MSR = lw;
           break;     
    }

	// CTS = 1  can tx
	// CTS = 0  dis tx
    if (imU1MSR & 0x10) {
       TxSt |= BIN(010);
    }
	
/*******************************/
/*******************************/
/*******************************/
	run = u1TxSt;
	switch(TxSt) {
 
          //  CTS! stop tx
	 case BIN(001):
	      run  = TX_CTS_SET;
	      if (u1TxRdPtr == u1TxWrPtr) {
                run |= TX_NO_DATA;
	      }
	      U1TER  = 0; // TxEn = 0
	      break;
	 	  
          // CTS released
	 case BIN(010):
	 case BIN(110):
	      if (run   &   TX_CUR_TX) {
	          run   &= ~TX_CTS_SET;
	          U1TER = 0x80; // TxEn = 1
	          break;
	      }
	      
	 case BIN(011):
              lw = u1TxRdPtr;
          if (lw == u1TxWrPtr) {
              run   = TX_NO_DATA ;
          } else {       
              run   = TX_CUR_TX  ;
              U1THR = u1TxBuf[lw];
              if (++lw >= TX_BUF_SZ) {
                    lw  = 0;
              }
              u1TxRdPtr = lw;
          } 
          U1TER = 0x80; // TxEn = 1
          break;
	 	  
              //  CTS! stop tx
	 case BIN(000):	  
	 case BIN(100):
	      run   |= TX_CTS_SET;
	      U1TER  = 0; // TxEn = 0	      
	      break;
	 	  
	      // state =  "1x1" не могут быть
	 default:
	      break;
	}
	u1TxSt = run;
	
	
  /* Update VIC priorities */
	VIC2138->VICVectAddr = 0;
}

/******************************************************************************
 * DESCRIPTION:
 * 
 *****************************************************************************/
static u16_t GSMU__GetTxFreeSz(void) {
 REG_t s32_t d = u1TxWrPtr - u1TxRdPtr;

   if (d < 0) {
       d += TX_BUF_SZ;
   }
   return TX_BUF_SZ - d;
}


/******************************************************************************
 * DESCRIPTION:
 * 
 *****************************************************************************/
void GSMU__TxData(u8_t *src,u16_t _sz) {
 REG_t u32_t Min     ;
 REG_t u32_t lw      ;
 REG_t u32_t sz = _sz;
 
   while (sz) {

      while((lw = GSMU__GetTxFreeSz()) < 8){};
 	  
      lw -= 2         ; // protect for buffer ovf
      Min = MIN(lw,sz); // get min av sz
      sz -= Min       ; // correct sz
      lw  = u1TxWrPtr ;
  	  
      while(Min--) {
        u1TxBuf[lw] = *src++;
        if   (++lw >= TX_BUF_SZ) {
                lw  = 0;
        }
      }
      u1TxWrPtr = lw;

      //////////////
      disable_IRQ(); // "???"
      if (u1TxSt == TX_NO_DATA) {
           lw     = u1TxRdPtr;  
	   U1THR  = u1TxBuf[lw];
  	   if (++lw >= TX_BUF_SZ) {
  	         lw  = 0;
  	   }
           u1TxRdPtr = lw;		
      }
      enable_IRQ(); // "???"
      //////////////      
   }
}

/******************************************************************************
 * DESCRIPTION:
 * 
 *****************************************************************************/
void GSMU__Init(void) {
    U1IER     = 0;
    u1TxSt    = TX_NO_DATA;
    u1TxWrPtr = 0;
    u1TxRdPtr = 0;
    u1RxWrPtr = 0;
    u1RxRdPtr = 0; 
    imU1MSR   = 0x10;
    // RBR + THRE INT enable + modem status
    U1IER     = BIN8(00001011);	
}