не совсем по 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);
}
-
- Ответ: Вот как я это делаю: Abo(2046 знак., 03.08.2005 16:57,
)
- ps Romario(472 знак., 02.08.2005 21:08,
)
- Ответ: Вот как я это делаю: Abo(2046 знак., 03.08.2005 16:57,