.:madworm:.'s photos

The heads

Coil + parking position bumper

The heads

Harddisk hub motor

23 Jan 2011 201
It is indeed a BLDC motor. The coils are Y-wound.

Harddisk hub motor

23 Jan 2011 215
It is indeed a BLDC motor. The coils are Y-wound. The left pad goes to the center point N, the remaining are the 3 phases U,V,W. Single-coil-resistance is about 1.6 Ohm. The disk's PCB contains a Hitachi HA13645 driver. Unfortunately I just can't find a datasheet for that. From what I've read so far, driving these with back EMF detection on the un-driven coils could be quite difficult. scholar.lib.vt.edu/theses/available/etd-09152003-171904/u... www.atmel.com/dyn/general/tech_doc.asp?doc_id=10416

Harddisk - stuff thrown away

Optimized ISR runtime - 8th pulse

21 Jul 2011 138
3.3µs

Optimized sampling-ISR runtime

21 Jul 2011 147
Now the pulses of trace #3 are more or less constant ;-) Much later it came to my mind that calculating _BV(bit) every single time is just stupid, so I distributed the bit shifting to each invocation of the ISR: static uint8_t bit_value = 1; if( (bit_value > 0) && (bit_value <= 0x80) ) { // 0x80 = 0b10000000 - read data-bits 0...7 if( (PINA & _BV(PA0)) ) { soft_uart_rx_byte |= bit_value; } else { soft_uart_rx_byte &= ~bit_value; } [...] The compiler is also quite clever in optimizing the first if() statement: 4c4: lds r24, 0x0062 4c8: mov r25, r24 4ca: subi r25, 0x01 ; 1 4cc: sbrc r25, 7 4ce: rjmp .+40 ; 0x4f8 4c4: load 'bit_value' to R24 4c8: move R24 to R25 (to keep R24 safe) 4ca: subtract 1 from R25 <-- this is where the magic happens 4cc: check if BIT7 (MSB) is set in R25, if so SKIP 0x4ce 4ce: jump to 0x4f8 'bit_value' should be a) greater than 0 and b) smaller or equal 128. For an uint8_t that means the following: a) At least one bit must be set b) Either the MSB is set, or any combination of the lower bits Condition a) is almost completely included in b) Now subtract one. b) Now only bits 0-6 will be set, bit 7 will have to stay empty ! a) If 'bit_value' started as '0', it would now be 255. the MSB would be set. The if()-statement is now reduced to a _single_ check if BIT7 is empty.

Optimized ISR runtime - 1st pulse

21 Jul 2011 129
3.2 µs

1st optimization attempt - 8th pulse

21 Jul 2011 158
8.1µs

1st optimization attempt - 1st pulse

21 Jul 2011 144
Still 4.0µs...

1st optimization attempt

21 Jul 2011 150
When dealing with this I realized (finally) that I could remove duplicate code and use this as the replacement: uint8_t bit_value = _BV(bit); if(bit <= 7) { // read data-bits 0...7 if( (PINA & _BV(PA0)) ) { soft_uart_rx_byte |= bit_value; } else { soft_uart_rx_byte &= ~bit_value; } [...] Now the _BV(bit) expression has to be evaluated just once. But that didn't help at all. It seems the compiler had already optimized the previous code.

Starting values - 8th pulse

21 Jul 2011 145
8.3µs

Starting values - 1st pulse

21 Jul 2011 167
3.7µs

Starting values - overview

21 Jul 2011 158
By accident I had observed that the runtime gets longer and longer. See here as well. Code excerpt: if(bit <= 7) { // read data-bits 0...7 if( (PINA & _BV(PA0)) ) { soft_uart_rx_byte |= _BV(bit); } else { soft_uart_rx_byte &= ~_BV(bit); } [...] As shown here , the _BV(bit) part gets turned into a loop. As 'bit' is a variable, it can't be replaced by a number at compile time. And the loop gets longer for higher bits.

Fully interrupt driven soft-uart receiver

17 Jul 2011 166
By accident I stumbled across my 'system-ticker' interrupt today. As it happens it conveniently ticks at 1MHz! One tick of timer0 is one microsecond. Microsecond timing is exactly what is needed for receiving serial data. The sampling interrupt (TIM0_COMPA_vect) is now invoked at the right time by setting OCR0A = TCNT0 + FULL_BIT_DELAY.

Fully interrupt driven soft-uart receiver

17 Jul 2011 180
By accident I stumbled across my 'system-ticker' interrupt today. As it happens it conveniently ticks at 1MHz! One tick of timer0 is one microsecond. Microsecond timing is exactly what is needed for receiving serial data. The sampling interrupt (TIM0_COMPA_vect) is now invoked at the right time by setting OCR0A = TCNT0 + FULL_BIT_DELAY.

Fully interrupt driven soft-uart receiver on an AT…

17 Jul 2011 316
By accident I stumbled across my 'system-ticker' interrupt today. As it happens it conveniently ticks at 1MHz! One tick of timer0 is one microsecond. Microsecond timing is exactly what is needed for receiving serial data. The sampling interrupt (TIM0_COMPA_vect) is now invoked at the right time by setting OCR0A = TCNT0 + FULL_BIT_DELAY.

5899 items in total