Developing a universal module

More
13 Jan 2014 21:27 #18486 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module

victzh wrote: Do you still use schematics from post #18347? Why did you connect TXEN/RXEN (PA_EN/LNA_EN) to their GPIOs for A7105 and CC2500? Wouldn't it be simpler to use a chip with more IO pins?

The schematic changed slightly, but that is about it. As far as using explicit pins. I think this solution is preferable. This will be my recommended way to wire the modules for folks without a programmable switch. It is just as easy to control with gpio as with the switch, but will work for more people. In the case of the awa24s, I ended up doing exactly that as I didn't have enough GPIO.

Another question - you have at least one pin which could be used for nRF24L01's CE, wouldn't it be wise to connect it? TX to RX and back is much faster with CE than with powerdown/powerup.

Because I haven't worked with the nrf, and didn't know that. I'll do it in the next revision though.
As far as using a larger atmel chip, I'm already out of space for the form-factor I want, so unless I go SMT, it is hard to use a larger chip. However, for the PCB, I ended up putting the AVR on the back which does provide enough space I could probably fit a 20-pin DIP. We'll see how this revision works, and make updates as needed. I still have 3 unused I/O on the ATTiny24. I am not sure the AVR can provide enough current for the PAEN pin an the AWA24S. If not, I'll need to add a FET too. I'm just trying to keep this as simple to build as possible with as few discrete components. I currently only need a single 10k resistor in addition to the board and AVR chip. And even that we don't strictly need.

Please Log in or Create an account to join the conversation.

More
13 Jan 2014 21:29 - 13 Jan 2014 21:33 #18487 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
For those interested, here is the Version 1.0 schematics and gerber for the programmable switch module.

Having used it now, I'm not 100% convinced on KiCad either. I hate how selection, delete and rubberbanding work. The autorouter works well, but is kludgey to use. Having the libraries be in text syntax is a nice benfit though.

While I don't use board-design software at my day job, the EDA tools I do use are so much better designed than tools like Eagle/KiCad that I find it extremely frustrating to work with them.
Attachments:
Last edit: 13 Jan 2014 21:33 by PhracturedBlue.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 05:37 #18495 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
Well, I already found one bug in my schematic. The CSN pin cannot be overloaded onto !RESET without setting the RESET-DISABLE fuse, which would then render future programming impossible.

Since the pinout on the connector is not fixed, this can be resolved by adding an extra wire between an alternate pin (PB0) and the connector.

That was a pretty rookie mistake, but this is my 1st time really working with an AVR.

I got my ATTiny84A today (ahead of expectations), and I'm about done with the 1st pass coding. Since I'm not really familiar with the AVR, it'll probably take me a little while to figure out how to set the registers properly to make the pins function as I want them to.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 07:25 #18496 by SadSack
Replied by SadSack on topic Developing a universal module
Give eagle ago, I've got few working library parts done and if anyone posts details of others I could add them. Couldn't get on with kicad but did struggle with Eagle but a lot more how to guides out there.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 07:47 #18497 by blackmoon
Replied by blackmoon on topic Developing a universal module
What's the actual size of the board ?

Thank you.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 14:44 #18498 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module

SadSack wrote: Give eagle ago, I've got few working library parts done and if anyone posts details of others I could add them. Couldn't get on with kicad but did struggle with Eagle but a lot more how to guides out there.

I've designed several boards with Eagle. This is the 1st time I've used KiCad though. I'll stick with it for this project. I don't know what I'll do next time around.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 14:51 #18499 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
the board itself is ~ 23x48mm, however, once you add the modules, it comes out closer to 45mmx48mm, and will be quite thick as the modules are layered on top of each other

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 16:41 - 14 Jan 2014 16:41 #18501 by cstratton
Replied by cstratton on topic Developing a universal module

PhracturedBlue wrote: Well, I already found one bug in my schematic. The CSN pin cannot be overloaded onto !RESET without setting the RESET-DISABLE fuse, which would then render future programming impossible.


There's a really tiny UART bootloader for the ATtiny85 which you might be able to port. That could let you burn the reset fuse but still program the chip.

Perhaps you could even get it so that you could program it from the STM32, by dumping a new file onto the mass storage, or adding a virtual serial passthrough mode.
Last edit: 14 Jan 2014 16:41 by cstratton.

Please Log in or Create an account to join the conversation.

More
14 Jan 2014 22:42 - 14 Jan 2014 23:13 #18511 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
I've got the code working in the simulator now. I'm not happy with the interrupt handler latency, and may hand-code it. The compiler won't seem to do it in less than 30 cycles. Given the limitations of the AVR instruction set, I'm not sure I can do a lot better, but I'll see what I can manage.

This is the code I'm trying to reduce:
ISR(PCINT1_vect) {
        //CSN change
    if (CSN) {
        PORTA |= global_toggleA;
        PORTB |= global_toggleB;
    } else {
        PORTA &= ~global_toggleA;
        PORTB &= ~global_toggleB;
    }
}
There really isn't much to it
Last edit: 14 Jan 2014 23:13 by PhracturedBlue.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 02:05 #18516 by hexfet
Replied by hexfet on topic Developing a universal module

PhracturedBlue wrote: This is the code I'm trying to reduce:

I'm making some guesses here but have an idea , though it seems slightly fragile (and crazy...stopped by the growler shop on the way home : )

If this interrupt happens on both edges of CSN, and you can initialize PORTA and PORTB based on what the value of CSN will be on the first interrupt, I think the code below is equivalent. If you can't predict the first interrupt value, a possibility would be to use the routine you posted first, then replace it with the following for subsequent interrupts. Every CSN interrupt would have to be serviced before the next CSN change for this to work.
ISR(PCINT1_vect) {
  //CSN change
  PORTA ^= global_toggleA;
  PORTB ^= global_toggleB;
}

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 03:38 #18517 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
I can't take the risk that we miss an edge, so I'd rather have something more robust. I ended up using this:
ISR(PCINT1_vect) {
    //CSN change
    if (CSN) {
        PORTA |= global_toggleA;
        PORTB |= global_toggleB;
        } else {
        PORTA &= global_toggleNOTA;
        PORTB &= global_toggleNOTB;
    }
}
note that toggleA,B, NOTA, and NOTB are all assigned to registers (so I burn 4 registers with these values).

The current code is 21 cycles if I counted correctly. The PortA value is updated within 12cycles (+4 to get to the interrupt handler). I could take
3 instructions off the front and 2 off the end if I hand coded it (and another 2 off the front and 2 off the back if I leave interrupts enabled during the handler, which is probably safe to do given this is the only interrupt handler). But we'll leave it like this for now. It is a lot more readable.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 05:53 #18520 by victzh
Replied by victzh on topic Developing a universal module
That is why I wanted to use CPLD, not an MCU. My Verilog is quite weak, and it's hard to find small CPLD with enough elements to handle the logic - the more elements in CPLD, the more pins.

A trade-off would be to use a multiplexor to handle the CSN, everything else can be handled by MCU.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 06:10 #18522 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
Sure, everything is tradeoff. The benefit of this design is its simplicity. The board + MCU should be obtainable for < $5 and is easy to build. Adding more parts increases the complexity, and reduces the utility. Getting an MCU with a fatser clock would also work.
Anyhow, 12 + 4 cycles means a 2us delay between setting CSN and starting SPI transfer. I don't think that'll be too much. And as I said if I hand-code the interrupt routine, I can reduce that to 1.5us.

If it is still unacceptable, I'll experiment with the Pic MCUs. They run at 32MHz with the internal oscillator. Even though most instructions take 4cycles to execute, I believe the interrupt handler is only 4 cycles, so it is possible the CSN could actually be switched in 0.5us or less.

The board is actually compatible with the PIC MCU with no modification (though it requires an external programmer)

Please Log in or Create an account to join the conversation.

  • rbe2012
  • rbe2012's Avatar
  • Offline
  • So much to do, so little time...
More
15 Jan 2014 06:49 #18524 by rbe2012
Replied by rbe2012 on topic Developing a universal module

PhracturedBlue wrote: ... (and another 2 off the front and 2 off the back if I leave interrupts enabled during the handler, which is probably safe to do given this is the only interrupt handler).

As far as I remember from my experiences with coding for ATMega8 and 32 the call of an interrupt routine automatically disables interrupts (no need for "cli") and enables them again when executing the "reti" command.
Could you spare some time when using single bit operations (like sbi/cbi - set/clear bit in i/o-register) - should be faster than a read-modify-write.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 07:05 #18526 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
Well, I just measured it on my logic analyzer, and the current code takes 3us to enable the CSN pin. That is too slow for the way the CS pins are programmed today, so I need to do a bit of work. On the plus side the module looks like it is working as intended inside my Devo8 (I can select the pin to toggle and make it do so with CSN). No more tonight, but with a little luck, I'll have this working tomorrow.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 07:11 #18527 by victzh
Replied by victzh on topic Developing a universal module
Does not PIC have 4 clock per instruction in contrast to AVR's 1:1? That means the same 8 mega instructions per second.

1.5-2us may be OK, especially if you can insert a small delay between asserting CS on main MCU and actual SPI transfer. At usual 4MHz SPI clock speed this is comparable with a transfer of one byte, so the penalty is not that bad.

On the other hand, CD4052 multiplexer costs $0.50 in quantities of 1. Design is a little bit more complex, I admit.

Anyway, we have several ways of solving it, so if pure MCU solution works unreliably there is always another option.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 15:01 #18535 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
yes pic runs at 4clocks per instruction, but my understanding is that interrupts are handled faster.

Anyhow, I figured out last night that I don't need to and/or the register. So i ended up with this:
ISR(PCINT1_vect, ISR_NAKED) {
    //CSN change
    #if 0
    if (CSN) {
        PORTA = global_A;
        //PORTB = global_B;
    } else {
        PORTA = global_NOTA;
        //PORTB = global_NOTB;
    }
    #else
    asm("mov r14, r17");
    asm("sbis 0x16, 0");
    asm("mov r14, r16");
    asm("out 0x1b, r14");
    #endif
    reti();
}
(for some reason gcc was doing an extra copy, and generating illegal code with the 'naked' attribute, so I ended up doing it in asm anyhow. End result: 13 cycles to set CSN (at least according to the simulator). I don't think I can do any better than that.

Please Log in or Create an account to join the conversation.

  • rbe2012
  • rbe2012's Avatar
  • Offline
  • So much to do, so little time...
More
15 Jan 2014 15:53 - 15 Jan 2014 15:54 #18539 by rbe2012
Replied by rbe2012 on topic Developing a universal module
I am not sure how many inputs you have unused but you might connect the CSN to an interrupt enabled pin of PORTA and a second of PORTB and program the trigger values for the different edges (e.g. rising edge for INT0, falling edge for INT1). So you only have to set one value, but need two ISRs. This might be the fastest way.
ISR(PCINT0_vect, ISR_NAKED) {
    //CSN rising up
    asm("out 0x1b, r17");
    reti();
}
ISR(PCINT1_vect, ISR_NAKED) {
    //CSN falling down
    asm("out 0x1b, r16");
    reti();
}
And you will have identical time for both conditions.
Last edit: 15 Jan 2014 15:54 by rbe2012.

Please Log in or Create an account to join the conversation.

More
15 Jan 2014 18:14 - 15 Jan 2014 21:24 #18541 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
I think only int0 is capable of single-edge triggered interrupts. On the ATTiny84, I don't see anything that would allow controlling pcint0/1 edge direction.
It looks like even using an external oscillator isn't an option as at 3.3V the ATTiny can only handle 10MHz.
I think we're in the right range.
I've already coded CS_LO and CS_HI functions to add a delay after setting and they seem to be working in most cases. I'll hopefully have everything up and running later today.
Last edit: 15 Jan 2014 21:24 by PhracturedBlue.

Please Log in or Create an account to join the conversation.

More
16 Jan 2014 06:09 #18556 by PhracturedBlue
Replied by PhracturedBlue on topic Developing a universal module
Well, I bound to my Hubsan using the module today :)
Unfortunately I discovered another bug in the board design that is more critical: I used a resistor between MISO and MOSI to convert the A7105 3-wire SPI to 4-wire SPI. I had done this on my RPi (which doesn't really support 3-wire SPI) a while ago. Now I remember why I needed to run the RPi SPI at slower frequency: There is too much cap on the miso pin, and it cannot respond at 4MHz with the resistor in place. You could reduce the resistor size to resolve this, but at the direct cost of overall current. So The resistor needs to be removed, and the MOSI pin needs to be connected to the A7105 SDIO pin. I can do that by cutting the trace and adding a jumper, so it isn't the end of the world. I'll wait for the boards to come back and make sure the design is otherwise good before finalizing the 2nd revision.

Using the A7105 GPIOs to control the PA/LNA enables, seems to work great in my testing so far, but it means I need to go through each protocol and carefully verify I get it coded right each time we switch from Tx to Rx mode.

With the optimized ISR routine, the MCU can handle a CSN change within ~1.75us which is good enough for me, so I think this design is a winner.

Please Log in or Create an account to join the conversation.

Time to create page: 0.094 seconds
Powered by Kunena Forum