не совсем по 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, )