Forum Rule: Always post complete source code & details to reproduce any issue!
Page 4 of 4 FirstFirst ... 2 3 4
Results 76 to 79 of 79

Thread: Tutorial on digital I/O, ATMega PIN/PORT/DDR D/B registers vs. ARM GPIO_PDIR / _PDOR

  1. #76
    Thanks Leray,

    I had my doubts about applying the mask to GPIOB_PDOR. So the following should work?


    GPIOB_PDOR = (GPIOB_PDIR & ~b_mask) | (send_value & b_mask); // Modify only 6 bits in Port B


    I was thinking that if the syntax above will safely modify the value on the port, it wouldn't actually matter if the bits within the port are contiguous. With the correct mask I can access all the available bits within a given port and access them all simultaneously.

    Although a more straight forward parallel interface would be great, if I can get away with manipulating the ports using this approach, it would be versatile enough for my needs.

  2. #77
    Member
    Join Date
    Feb 2015
    Location
    Rians in Provence, France
    Posts
    62
    Quote Originally Posted by RichardPeteSharp View Post
    Thanks Leray,

    I had my doubts about applying the mask to GPIOB_PDOR. So the following should work?


    GPIOB_PDOR = (GPIOB_PDIR & ~b_mask) | (send_value & b_mask); // Modify only 6 bits in Port B


    I was thinking that if the syntax above will safely modify the value on the port, it wouldn't actually matter if the bits within the port are contiguous. With the correct mask I can access all the available bits within a given port and access them all simultaneously.

    Although a more straight forward parallel interface would be great, if I can get away with manipulating the ports using this approach, it would be versatile enough for my needs.
    You could be completely safe using GPIOB_GPIR (With 'I' as INPUT)for reading the state of the whole B register. And relaoad it after your boolean operations.

  3. #78
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,357
    I could be wrong but I have no idea why you would be looking at the state of the GPIOB_PDIR register? This is the Input state (read only register), of those IO pins on that object...
    You can readn GPIOB_PDOR - For the current output state of all IO pins on GPIOB... This register is Read/Write. (Page 2189 of my T3.6 PDF...)

    So you can do things like:
    Code:
    GPIOB_PDOR = (GPIOB_PDOR & ~b_mask) | (send_value & b_mask);
    I am not sure which N pins of the GPIOB you are using. But hypothetically you are using: Bits 0-5 for 6 bits, which quick look is something like pins:
    (16, 17, 19, 18, 49, 50)

    However I assume you realize that you run a risk with this code. For example suppose your code uses some form of interrupts, example an intervalTimer, and suppose your interval timer procedure does something like:

    Code:
    void myIntervalTimerProc() {
        digitalWriteFast(0, !digitalReadFast(0));
         (it's work)
    }
    And suppose you have the above code like: GPIOB_PDOR = (GPIOB_PDOR & ~0x3f) | (send_value & 0x3f);

    Now suppose your code is running, and just after it reads the GPIOB_PDOR but before it updates it, your ISR runs and changes the state of D0 (which is B16)
    When the ISR returns and your code completes the update of the GPIOB_PDOR you just throw away the updated state from the ISR...

    And these are fun bugs to track down.. Been there!


    Again there are ways to fix this, like:
    Code:
    	__disable_irq();
    	GPIOB_PDOR = (GPIOB_PDOR & ~b_mask) | (send_value & b_mask);
    	__enable_irq();
    or if you can stand the timings and a pins changing in two steps... Maybe something like:
    Code:
    	GPIOB_PSOR = send_value;   // assumes send_value only has the N bits set or cleared in it if not mask it.
    	GPIOB_PCOR = ~send_value & b_mask;
    These operators only muck with the bits you are using and as such are interrupt safe...

  4. #79
    That is a huge help. Your 2nd example that allows me to clear or set only the bits I'm using, without touching anything else, is absolutely perfect. Since I only send brief signals and already zero out the bits afterwards, it's actually more of a one step process for me to use GPIOx_PSOR to put a value on the port.

    I followed your lead and looked at the data sheets at https://www.pjrc.com/teensy/datasheets.html

    The "General-Purpose Input/Output (GPIO)" chapter in the T3.5 and T3.6 manuals was very concise and easy to follow. It's obvious once you know it, but that chapter put everything discussed in this thread into perfect context for me.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •