I need three time period for onewire data reading. Without writing any ISR and can I get required time periods by polling M0, M1 and M2 match register interrup flags. Following code is what I am working on and it doesn't work. Is there any missing settings else?
#define Presc 14 //--------------------------16 bit write ---------------------------- void onewire_write(short int bayt, short int data) // 6, 54, 10 { short int count, bits; bits = bayt * 8; #define AB 6 #define BC 60 #define DD 10 #define M0_i 1 // Bit <2:0> <s:r:i> Stop,Reset,Interrupt #define M1_i 1<<3 // Bit <5:3> <s:r:i> " #define M2_irs 7<<6 // Bit <8:6> <s:r:i> " T1PR = Presc; // Prescale 15, 60 MHz CClock, 15 MHz PCLCK T1MR0 = AB; // Wait this long T1MR1 = AB+BC; // Wait this long T1MR2 = AB+BC+DD ; // Wait this long T1MCR = M0_i | M1_i | M2_irs; // Interrupt,stop and reset settings of Match regs T1TCR = 0x02; // Reset timer1 for (count=0; count<bits; ++count) { output_low(); T1TCR = 0x01; // timer1 starts while(!(T1IR & 1)); // Wait for int flag if ( data&1 != 0 ) output_float(); // write 0 or 1 data >>= 1; while(!(T1IR & 2)); // Wait for int flag output_float(); // set 1-wire high again, while(!(T1IR & 4)); // Wait for int flag T1IR = 0x07; // Clear M2, M1, M0 interrupts } }
For disabling global interrupt, I need some time :) I haven't come to Interrupts chapter of "The Insider's Guide To The Philips ARM7-Based Microcontrollers" :)
void __asm __swi(12) disable_interrupts(void) ; void __asm __SWI_12 (void) { MRS R1, SPSR ORR R1, R1, #0xC0 // disable IRQ and FIQ MSR SPSR_c, R1 BX LR } // writing to the CPSR register requires entering privileged mode void __asm __swi(13) enable_interrupts(void) ; void __asm __SWI_13 (void) { MRS R1, SPSR BIC R1, R1, #0xC0 // enable IRQ and FIQ MSR SPSR_c, R1 BX LR }
if you are using the RealView compiler, you can also use its intrinsic functions to do the same.
float ds1820_read() { char busy=0,t2, t1, i; int tt=0; float result; __SWI_12();// disables Global Interrupt i=onewire_reset(); if(i==1) { print("*** Reset basarisiz ***"); return (-273.15); } onewire_write(0xCC); // skip rom write 1 byte onewire_write(0x44); // 44 ölçümü baslatir. while (busy == 0) busy = onewire_read(); onewire_reset(); onewire_write(0xCC); onewire_write(0xBE); t1 = onewire_read(); t2 = onewire_read(); __SWI_13();// enables Global Interrupt tt= ((int) t2<<8) | ((int)t1 & 0xFF); result = (float)tt / 16.0; //defauld conf. 12 bit resolution return(result); }
Dear Tamir, Is this a correct calling of the software interrupts you have given?
No. Use them like normal functions/function pointers:
disable_interrupts() ;
Do note that you must update your SWI.s file to use SWI functions. You can always use the native RealView intrinsic functions
void __disable_irq(void); void __enable_irq(void); void __disable_fiq(void); void __enable_fiq(void);
instead. This exempts you from making any further changes other than to include a header (no SWI.s changes needed).
I tried this
... enable_interrupts() ; ... disable_interrupts() ; ...
but compiler gave errors, saying undefined funtions enable..., disable... The code above with colored red function call was compiled and in the simulator called as ordinary function call. I know calling normal function is different than branching to an ISR by an interrupt source. AFAIK the latter changes the operation mode which may allow certain modifcation on the settings that are not allowed in user mode. Is this correct?
I think I should copy a SWI.s file to working folder and include to the project :)
Note that your timing is critical while doing the individual operations, such as reset (to a lesser degree), and reading or writing individual bits. But the onewire interface allows you to pause the transfer between the individual bits.
This allows you to only disable interrupts around each bit transfer, instead of having one huge (and very slow) section where interrupts are disabled for milliseconds.
Too long sections with interrupts disabled means that serial communication and other activities that are interrupt-driven may fail. For serial communication, you may get overruns because you don't pick up received characters before new ones arrives. Even when the processor have a receive FIFO, you still have to service the UART regularly.
Dear Westermark, you are absolutely right. So I will transfer the disable and enable interrupts call instruction to bit writing or reading loops of write and read functions.