Код
__ramfunc void irq_Receive()
{
PauseTimerBase->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase->TC_CCR = AT91C_TC_SWTRG;
source = regs->PIOA_PDSR&0x600;
if(source==0x200) {recA = recA>>1; i_shA++; recA = recA|0x80000000;} //A1
if(source==0x400) {recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF;} //B1
dummy = AT91C_BASE_PIOA->PIO_ISR;
}
{
PauseTimerBase->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase->TC_CCR = AT91C_TC_SWTRG;
source = regs->PIOA_PDSR&0x600;
if(source==0x200) {recA = recA>>1; i_shA++; recA = recA|0x80000000;} //A1
if(source==0x400) {recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF;} //B1
dummy = AT91C_BASE_PIOA->PIO_ISR;
}
при этом перезапускается таймер, который остчитывает паузу между принимаемыми словами. как только пришла пауза, таймер срабатывает и по прерыванию:
Код
__ramfunc void pause_timer_irq()
{
if(i_shA==32)
{
recDA[kA] = recA; kA++;
}
if(kA==12) send_to_host();
i_shA=0;
dummy = PauseTimerBase->TC_SR;
}
{
if(i_shA==32)
{
recDA[kA] = recA; kA++;
}
if(kA==12) send_to_host();
i_shA=0;
dummy = PauseTimerBase->TC_SR;
}
записывает данные в некий буфер.
но помимо этого одновременно может идти передача данных по прерываниюот другого таймера, работающего в режиме генератора:
Код
__ramfunc void timer0_irq_handler()
{
ii--; //счетчик переданных бит
if(ii==1) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}
MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;
if(datA&0x80000000) regA = 0x20000;
else regA = 0x0;
regs->PIOA_ODSR = regA|front;
datA = datA<<1;
dummy = MipsTimerBase->TC_SR;
}
{
ii--; //счетчик переданных бит
if(ii==1) {MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;}
MipsTimerBase->TC_RA = 30; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = 60;
if(datA&0x80000000) regA = 0x20000;
else regA = 0x0;
regs->PIOA_ODSR = regA|front;
datA = datA<<1;
dummy = MipsTimerBase->TC_SR;
}
Передача и прием идут с частотой 100 кГц. Приоритеты всех прерываний 7, то есть по идее они должны выполняться по очереди. Но при этом обработчик таймера паузы должен успеть все сделать до прихода следующего слова.
Передача и прием по отдельности работают нормально, без сбоев. Но при их одновременной работе прием не нарушается, а передача происходит с ошибками и в дальнейшем вовсе останавливается. Поэтому я и решил оптимизировать обработчики прерываний.
Для начала я решил все обработчики поместить в RAM, но тут столкнулся с интересной особенностью, если обработчик приемника void irq_Receive() не помещать в ОЗУ, то прием идет очень медленно, не успевает. Но, если обработчик передатчика void timer0_irq_handler() поместить в ОЗУ, то при одновременной работе приемника и передатчика (замыкание выхода передатчика на вход приемника) данные вообще не передаются, а если не помещать в ОЗУ то немного данных передаются. Как правильно размещать обработчики прерываний в ОЗУ и значительно ли это ускоряет работу?