This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

direct referrence to GPIO pins

another newbie question.

I have a piece of code that I am porting from PICC. In PICC, you can make reference to specific pins ("#define sclk GPIO5" for example), and in your code, you can write to sclk to change the pin output on GPOI5. This makes porting code or changing pin layout so much easier as you can simple redefine sclk to a different pin to make the code work.

ARM seems to prefer to change its pin output through IOSET / IOCLR.

To make the existing PICC code work, I would prefer to be able to define certain pins logically, and change their states by referencing their logic names.

how do you do that in ARM? Thanks in advance.

Parents
  • "Because ARM sells cores, different ARM chips can have different ways to control the GPIO."

    I thought one of the unanswered questions from the very beginning of this thread is while there are many possible different ways to control gpio, none of the many vendors decided to implement it the PIC way.

    "If you still thing all ARM chips are identical, then you haven't read this thread, and you have not spent time looking through the datasheets for a couple of different chips."

    if you still think that others think all ARM chips are identical, then you haven't read this thread. We passed that point before this thread got started. let's move on.

    "Incorrect."

    what is incorrect?

    you guys write a lot. I just don't know if your writing addresses the questions asked. But I do appreciate your time / efforts and I am learning from this conversation, bit by bit.

Reply
  • "Because ARM sells cores, different ARM chips can have different ways to control the GPIO."

    I thought one of the unanswered questions from the very beginning of this thread is while there are many possible different ways to control gpio, none of the many vendors decided to implement it the PIC way.

    "If you still thing all ARM chips are identical, then you haven't read this thread, and you have not spent time looking through the datasheets for a couple of different chips."

    if you still think that others think all ARM chips are identical, then you haven't read this thread. We passed that point before this thread got started. let's move on.

    "Incorrect."

    what is incorrect?

    you guys write a lot. I just don't know if your writing addresses the questions asked. But I do appreciate your time / efforts and I am learning from this conversation, bit by bit.

Children
  • "do BFI/BFC count?"

    Keil documentation: "Bit Field Clear and Bit Field Insert. Clear adjacent bits in a register, or Insert adjacent bits from one register into another."

    Note that they target a register, not a memory address. So to set a bit in a memory-mapped address, you must:
    - load the memory address (GPIO latch register)
    - use your BFI/BFC instruction.
    - store back to the memory address (GPIO latch register)

    This is totally different from having the ability to set or clear bits directly in memory, since the BFC and BFI instructions are affected by the load latency. Set and clear registers on the other hand are write-and-forget. If the store buffer has room for the store, the ARM will be able to directly process the next instruction without any stalls.

  • "Note that they target a register, not a memory address. "

    OK. how about BSF/BCF? here is what Microchip has to say about them:

    "BCF Bit Clear f
    Syntax: [ label ] BCF f,b
    ...
    Description: Bit 'b' in register 'f' is cleared."

    "BSF Bit Set f
    Syntax: [ label ] BSF f,b
    ...
    Description: Bit 'b' in register 'f' is set."

    does it look like BCF/BSF also work on registers?

    wouldn't that make them identical to the ARM instructions?

  • Earlier in this thread you were referring to Cortex-M3 bit-banding. Not being familiar with PIC, I assume this would be the closest mechanism (in ARM world) to what you are looking for.

    However, bit-banding is not quite the right thing if you have to change several bits simultaneously. And by that I mean exactly at the same time. Don't know how PIC addresses that.

    To implement your example on a Cortex-M3 controller, you'd have to determine the bit address of a port in some data output register (you'll find examples all over the place). By defining a variable at that address, you can easily implement your sclk thing.

    infocenter.arm.com/.../Behcjiic.html

    Best regards
    Marcus
    http://www.doulos.com/arm/

  • But f in this case represents a register similar to the SFR in the 8051, i.e. it is a special region of memory.

    For a PIC16, f is a value between 0 and 127, specifying a memory address within this special SFR memory region. Some of these bytes will represent the status register (carry or zero bit) and some of these bytes will represent GPIO pins.

    The ARM has real hard registers. The registers in the ARM does not have a memory address, so a memory pointer can not access the ARM registers. And instructions working on registers can only modify the existing registers, not bytes or words in memory.

    In the end - if you want a processor that can declare bit-sized variables, you may consider a PIC or 8051 processor. The ARM core is not designed for bit variables. It has no bit-addressable memory, and no instructions to read or write individual bits in any such memory. Working with bytes or larger, the ARM requires either the hardware or the software to perform and/or/xor/not to modify individual bits in a memory cell - and since it separates registers from memory, the GPIO control will have to be memory-mapped.

    It would be possible to create an ARM core that either drops some of the registers, to use the name of these registers to control I/O. Or create an ARM core that keeps all registers, but defines that BFI/BFC are exception instructions that will only be able to access a subset of the registers, but instead also access GPIO. But ARM hasn't seen a reason to, since the customers has not shown any interest. And the customers can not modify an ARM core, since they will just get a hard macro cell to connect to their own logic.

    In the end, you will have to either select another processor, or live with the design choices that ARM has made for the processor core. The ARM is not a PIC and it is not a 8051. But for most users, this doesn't matter. The important thing isn't what instruction sequences you need to access a port pin. The important thing is how fast you can toggle them, and what cost it will take to run the chip at the required clock frequency and to have the required amount of flash.

    In the end, there is very few situations where the ARM can't match a 8051 in capability, cost or speed. The biggest reason for a PIC is probably if you need very, very few pins or need one of the NanoWatt series chips.

  • Ashely;
    It still appears that you are more intent on defending the PIC design than understanding the ARM when no one has challanged the PIC design. The statement is just the ARM concept is different.
    Instead of attempting to redesign the ARM core, why don't you review a few of the examples in the Keil toolset.
    What part of setting/clearing a bit troubles you?

    The GPIO register addresses are defined in the furnished header files. The Mask and Direction registers are normally set one time in a GPIO init module.

    Then:
    #define sensor_pwr_on 0x00001000
    #define sensor_pwr_off 0x00001000
    #define set_two_bit_on 0x00001001

    IOSET1 = sensor_pwr_on; //Zero bits are ignored
    IOCLR1 = sensor_pwr_off;

    IOSET1 = set_two_bits_on;

    In the MCB23xx Blinky example they use a macro definition then write:

    LED_E(0) // LED OFF
    LED_E(1) // LED ON

    So there are many different ways to get symbolic addressing of single bits.

    Bradford

  • Marcus, thank you so much.

    so GPIO A in LM3S628, per the datasheet, is at 0x4000.4000 - 0x4000.4FFF (24 bits for an 8-bit port? for compatibility reasons?). so its 0th pin / bit (0x4000.4000) should be a word at 0x4200.0000+0x4000 << 7 + 0x00<<2?

    if I want to set the 0th pin to 1, do I just set that word to anything other than 0?

    yeah, this is hugely helpful. I hope the mapping is consistent at least within the Cortex-M3 family?

    thanks a lot.

  • "Don't know how PIC addresses that."

    in PIC, you can assign a value to the port to change the bits at the same time.

    so GPIO=0b10101010 will set some bits and clear others at the same time.

    GPIO1=1 will just set the 1st bit, and GPIO0=0 will clear the 0th bit, sequentially of course.

  • "It still appears that you are more intent on defending the PIC design than understanding the ARM when no one has challanged the PIC design. "

    Al, once you start questioning a person's intent, you are going down a very slippery slope.

    let's just leave it at that.

  • "The ARM core is not designed for bit variables."

    I think that's the case. the reasons given earlier about latency, gpio off bus, or the business model, etc. are really not fundamental. It appears that for some reason, ARM or their vendors decided that that was the way for this particular chip. why / how they did that I don't know, maybe we will never know.

    "It has no bit-addressable memory,"

    apparently until the Cortex chips.

  • "I think that's the case. the reasons given earlier about latency, gpio off bus, or the business model, etc. are really not fundamental."

    They are very fundamental - when a manufacturer buys a core and adds peripherial functions around the core, they are limited by what the core allows. load/modify/store is affected by latencies, so such updates must be close to the core, which is the reason why the chip manufacturers has looked for alternatives that removes the need for the "load" part.

    The other alternative would have been to have the GPIO latches inside the core to allow single-clock access. Or replacing some registers with GPIO latches, allowing the modify instructions to directly modify the port pins.

    From the fact that C does not have bit variables, it should be quite obvious that bit addressable memory is not a generic feature available in all processors. It is also a feature not available in "normal" memory, but something that requires a special memory interface - either that the bit addressable memory is part of the core (8051 or PIC) or that the bit addressable memory is connected to a memory controller with built-in support for either addressing single bits, or for loading a word and set/clear a bit and writing back the word.

    I have written multiple times that the ARM is a load/store architecture and that modifying a single bit in a larger word requires the core to wait for the load operation. That means a problem with latencies, which you decided to follow up by wondering why the chip manufacturers haven't changed the core.

    I did also write the following:
    The ARM core doesn't have bit-manipulating instructions, so unless a specific manufacturer has spent one byte for each bit, you can't update a single bit in a port without either:
    - use a chip that have a mask register to write-protect some bits.
    - do a read/modify/write cycle, and let the processor stall for whatever number of cycles it takes to fetch the read data.

    The bit-banding in the Cortex-M3 chip is the only way you can get the ARM instruction set to access individual bits without requiring the core to also have to read the neighbour bits, i.e. having the core suffering from read latencies.

    Because of the large address space of the ARM, and instructions that are comfortable addressing the full address space, it is possible to waste a part of the address space for this method, allowing support without any C extensions. The only problem for the compiler is that it will not know about aliasing between the multiple addresses that maps to the same port, but it is enough to declare the addresses as volatile to make sure that the compiler doesn't try to cache the latch data.

  • "The bit-banding in the Cortex-M3 chip is the only way you can get the ARM instruction set to access individual bits without requiring the core to also have to read the neighbour bits, i.e. having the core suffering from read latencies."

    correct, except that the Cortex chip is an ARM core doesn't run the ARM instruction set.

  • > if I want to set the 0th pin to 1, do I just set that
    > word to anything other than 0?

    The LSB determines the value. But do keep in mind that
    this will actually result in a R-M-W access on the bus.
    If that is an issue in your application you should get used to using set/clear registers that are quasi-standard
    on ARM MCU. If you are considering a switch from PIC to ARM, that might be a good idea anyway.

    It is not that hard to search/replace 'sclk = 0' with a suitable macro definition.

    > I hope the mapping is consistent at least within the
    > Cortex-M3 family?

    The concept is consistent, but register addresses are not.

    Regards
    Marcus
    http://www.doulos.com/arm/

  • The Thumb2 instruction set is not a new instruction set. It is basically a subset of the full ARM instruction set, which is also why some cores can directly jump between ARM and Thumb mode. Being a subset just allows the Thumb instructions to have a 16-bit base size instead of 32-bit.

    Switching to the Thumb2 instruction set will not modify the behaviour of the core. The core is still a load/store design, where you operate on registers, and not on memory.

    This means that any limitations you see with the ARM instructions should most probably be seen with the Thumb2 instructions too.

  • I think that, I don't really understand this thread. But I had tried to.

    I found something:

    infocenter.arm.com/.../index.jsp

    Cortex-M3 Technical Reference Manual

    12.10. Bit-band accesses

    The System bus interface contains logic that controls bit-band accesses as follows:

    * It remaps bit-band alias addresses to the bit-band region.

    * For reads, it extracts the requested bit from the read byte, and returns this in the Least Significant Bit (LSB) of the read data returned to the core.

    * For writes, it converts the write to an 'atomic' read-modify-write operation.

  • My take on it is that for the Cortex-M3, it will be similar to a normal write for the processor - the write operation gets into the store cache so the processor can continue with the next operation unless the processor gets stalled because of too many outstanding writes.

    In this general case, where you have a huge memory block with bit-band access, the mapping between bits and words must be part of the memory controller logic.

    For a classic ARM chip, a manufacturer will have the ability to do simething similar - either for a large memory region or for specific registers. In the case someone decides to do it for a large region, they will have to implement it in the memory controller logic. For specific registers (such as a GPIO latch) it would be possible to add the set/clear logic directly into the port logic and remove the need for a load/modify/store.

    The advantages with Coretex-M3, is that it reduces the gap between the high-end and low-end implementations.