Author Topic: SAM mcu Low level port driver  (Read 372 times)

0 Members and 1 Guest are viewing this topic.

Offline hsn93

  • Regular Contributor
  • *
  • Posts: 86
  • Country: bh
SAM mcu Low level port driver
« on: July 09, 2018, 11:45:46 am »
hello,

i didnt know where i should post in Beginners or microcontroller forum..

i decided to post here because i feel its simple question:

im trying to write low level port driver for SAMD21 series mcu, copying codes from ASF and this what i did:

Code: [Select]
#define LED_0_PIN PIN_PA20
 #define LED_0_PIN_MASK (1U << (LED_0_PIN & 0x1f))


static inline void _gpio_set_OUTPUT(const uint8_t pin)
{
volatile PortGroup *pin_port = (volatile PortGroup *)(&(PORT->Group[pin / 32]));
pin_port->DIR.reg = (1U << (pin & 0x1f));
pin_port->PINCFG[pin & 0x1F].reg = PORT_PINCFG_DRVSTR;
}



static inline void gpio_set_pin_level(const uint8_t pin, const bool level)
{

volatile PortGroup *pin_port = (volatile PortGroup *)(&(PORT->Group[pin / 32]));

if (level) {
pin_port->OUTSET.reg = (1U << (pin & 0x1f));
} else {
pin_port->OUTCLR.reg = (1U << (pin & 0x1f));
}
}


my question is : am i doing this right way, to set-up pin high and low ?

should i call the function like this (without disable cpu irq) ? :
Code: [Select]
//cpu_irq_disable();

_gpio_set_OUTPUT(LED_0_PIN);
gpio_set_pin_level(LED_0_PIN,1);

//cpu_irq_enable();

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 5943
  • Country: us
    • Personal site
Re: SAM mcu Low level port driver
« Reply #1 on: July 09, 2018, 04:52:35 pm »
It looks ok.

There is no need to disable the interrupts unless your application needs it and can't tolerate potential small delay. Keep in mind that if output was not set previously, then it first will be driven to 0 and then set to 1. If you don't want this glitch, then set the output value first and then enable the output.
Alex
 

Offline hsn93

  • Regular Contributor
  • *
  • Posts: 86
  • Country: bh
Re: SAM mcu Low level port driver
« Reply #2 on: July 10, 2018, 07:07:41 am »
do you mean that by default its "internal pull up" and when i set it up to output .. it will be driven low for short period until i set "OUTSET.reg" ??

so it will be like this:

---------------------------------------output
--------pullup----output 0----------drive 1
======1======0==========1===========
« Last Edit: July 10, 2018, 07:09:57 am by hsn93 »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 5943
  • Country: us
    • Personal site
Re: SAM mcu Low level port driver
« Reply #3 on: July 10, 2018, 07:15:49 am »
Since pull-up is enabled by setting the output to 1 while pin is configured as an input, you will be fine here.

But lets say you had no pull-up or pull-down, just a floating input (or external pull-up), so the output buffer was set to 0. This is not a problem since direction is configured as an input. But then you change it to an output which is high.

If you set the high level first, then it still would not matter, since the pin is still an input, so when you switch the direction, it will just cleanly go to "1".

On the other hand if you set the direction first, then the output will go to 0 before MCU get to setting the output value high.

Same principle applies to PMUX settings. You always want to configure and enable the peripheral before setting the PMUX.
Alex
 
The following users thanked this post: hsn93


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf