Код
CODE32
EXTERN fwu_uart1_impl
PUBLIC fwu_uart1_asm
fwu_uart1_asm: // я уж думал spurious interrupts мешали.
SUB lr, lr, #4;
STMFD sp!, {lr};
MRS lr, SPSR;
TST lr, #I_Bit;
BNE fwu_uart1_asm_ret;
BL fwu_uart1_impl;
fwu_uart1_asm_ret:
LDMFD sp!, {pc}^;
//////////////////////////////////////
struct my_dataseg_t
{
u8_t volatile tx;
bool volatile tx_ready;
bool volatile tx_empty;
};
__no_init my_dataseg_t ds;
unsigned const serSOURCE_THRE = 0x02;
unsigned const serSOURCE_RX_TIMEOUT = 0x0C;
unsigned const serSOURCE_ERROR = 0x06;
unsigned const serSOURCE_RX = 0x04;
unsigned const serINTERRUPT_SOURCE_MASK = 0x0F;
__arm void fwu_uart1_impl(void)
{
switch (U1IIR & serINTERRUPT_SOURCE_MASK)
{
case serSOURCE_ERROR:
ds.rx_error = true;
ds.rx_ready = true;
break;
case serSOURCE_THRE:
if (ds.tx_ready)
{
U1THR = ds.tx;
}
else
{
ds.tx_empty = true;
}
ds.tx_ready = false;
break;
case serSOURCE_RX_TIMEOUT:
case serSOURCE_RX:
ds.rx = U1RBR;
ds.rx_error = false;
ds.rx_ready = true;
break;
default:
break;
}
VICVectAddr = 0;
}
void send_byte(u8_t B)
{
while (true)
{
__disable_interrupt();
if (ds.tx_empty)
{
U1THR = b;
ds.tx_empty = false;
ds.tx_ready = false;
__enable_interrupt();
return;
}
else if (!ds.tx_ready)
{
ds.tx = b;
ds.tx_empty = false;
ds.tx_ready = true;
__enable_interrupt();
return;
}
else
{
__enable_interrupt();
while (ds.tx_ready) { power_off(); }
}
}
}
void start_transmit(void)
{
U1IER = 0;
line_driver(true);
ds.tx_ready = false;
ds.tx_empty = true;
U1FCR_bit.FCRFE = 1; // FIFO Enable
U1FCR_bit.TFR = 1; // TX FIFO RESET
U1IER_bit.THREIE = 1; // THRE Interrupt Enable
U1TER_bit.TxEn = 1;
}
void power_off(void) {}
////////////////////////////////////
Вот так передаю.
start_transmit();
u8_t const buf[] = {1, 2, 3, 4, 5, 6, 7, 8, '?'};
for (u8_t const * i = BEGIN_OF_ARY(buf); i != END_OF_ARY(buf); ++i)
{
send_byte(*i);
}
while (true) {} // тут останавливается и ничего больше не передается. [/font]
EXTERN fwu_uart1_impl
PUBLIC fwu_uart1_asm
fwu_uart1_asm: // я уж думал spurious interrupts мешали.
SUB lr, lr, #4;
STMFD sp!, {lr};
MRS lr, SPSR;
TST lr, #I_Bit;
BNE fwu_uart1_asm_ret;
BL fwu_uart1_impl;
fwu_uart1_asm_ret:
LDMFD sp!, {pc}^;
//////////////////////////////////////
struct my_dataseg_t
{
u8_t volatile tx;
bool volatile tx_ready;
bool volatile tx_empty;
};
__no_init my_dataseg_t ds;
unsigned const serSOURCE_THRE = 0x02;
unsigned const serSOURCE_RX_TIMEOUT = 0x0C;
unsigned const serSOURCE_ERROR = 0x06;
unsigned const serSOURCE_RX = 0x04;
unsigned const serINTERRUPT_SOURCE_MASK = 0x0F;
__arm void fwu_uart1_impl(void)
{
switch (U1IIR & serINTERRUPT_SOURCE_MASK)
{
case serSOURCE_ERROR:
ds.rx_error = true;
ds.rx_ready = true;
break;
case serSOURCE_THRE:
if (ds.tx_ready)
{
U1THR = ds.tx;
}
else
{
ds.tx_empty = true;
}
ds.tx_ready = false;
break;
case serSOURCE_RX_TIMEOUT:
case serSOURCE_RX:
ds.rx = U1RBR;
ds.rx_error = false;
ds.rx_ready = true;
break;
default:
break;
}
VICVectAddr = 0;
}
void send_byte(u8_t B)
{
while (true)
{
__disable_interrupt();
if (ds.tx_empty)
{
U1THR = b;
ds.tx_empty = false;
ds.tx_ready = false;
__enable_interrupt();
return;
}
else if (!ds.tx_ready)
{
ds.tx = b;
ds.tx_empty = false;
ds.tx_ready = true;
__enable_interrupt();
return;
}
else
{
__enable_interrupt();
while (ds.tx_ready) { power_off(); }
}
}
}
void start_transmit(void)
{
U1IER = 0;
line_driver(true);
ds.tx_ready = false;
ds.tx_empty = true;
U1FCR_bit.FCRFE = 1; // FIFO Enable
U1FCR_bit.TFR = 1; // TX FIFO RESET
U1IER_bit.THREIE = 1; // THRE Interrupt Enable
U1TER_bit.TxEn = 1;
}
void power_off(void) {}
////////////////////////////////////
Вот так передаю.
start_transmit();
u8_t const buf[] = {1, 2, 3, 4, 5, 6, 7, 8, '?'};
for (u8_t const * i = BEGIN_OF_ARY(buf); i != END_OF_ARY(buf); ++i)
{
send_byte(*i);
}
while (true) {} // тут останавливается и ничего больше не передается. [/font]
Передается только первый байт. Причем в ds.tx остается последний передаваемый байт - '?'. Если отладчик поставить на U1THR = b; - он там остановится. Если нажимать "продолжить" - передаются все байты. Подскажите пожалуйста -- с утра голову ломаю.