SAMD10 digital read - Page 1
Forum section: electronics / beginners

author: n4alpaca
author_rank: Newbie
timestamp: November 10, 2017, 02:34:02 am
content: Hello, I've been struggling with getting digital read to work.This is how the code flowsPin initialization:Code:void gpio_init_pin(struct PIN p){uint32_t WRCONFIG = 0; // this MUST be a 32 bit number or writing to this address will have no effect//SET PIN MASKif(p.pinNum > 15){WRCONFIG += (1 << PORT_WRCONFIG_HWSEL_Pos ); // selects HWSEL for upper 16 pins}WRCONFIG += (1 << ( p.pinNum % 16 )); // base pin number subtracts 16 to fit into the pinmask[0,..,15] register// END SET PIN MASKif(p.mux == NOMUX){ // if there's no pinmuxing then its a standard input or output// set output. Pins are input by default, but writing 0 will make sure the pin an inputPORT->Group->DIRSET.reg = (p.dir << ( p.pinNum ));// end set output// set inputWRCONFIG += (p.in << PORT_WRCONFIG_INEN_Pos );// possibly power hungry method of read, otherwise we require two clock cycles to read// note: all pins in the byte (group of 8) will be sampled continuously.PORT->Group->CTRL.reg = (0xFF<<(8*(p.pinNum/8)));// end set input//set pullup/down enableif(p.pull != NO_PULL){WRCONFIG += (p.pull << PORT_WRCONFIG_PULLEN_Pos ); // if it's an output, this is a "don't care conditionPORT->Group->OUTSET.reg = (p.pull << p.pinNum); // determines pull up or down. Normally, this is used to set the level. Don't care condition on output}//end set pullup/down enable}else{WRCONFIG += (1 << PORT_WRCONFIG_WRPMUX_Pos);WRCONFIG += (1 << PORT_WRCONFIG_PMUXEN_Pos);WRCONFIG += (1 << PORT_WRCONFIG_WRPINCFG_Pos);WRCONFIG += (p.mux << PORT_WRCONFIG_PMUX_Pos );}Now, we can try to read.Code:int gpio_digital_read(struct PIN p){return (PORT->Group->IN.reg & (1<<(p.pinNum)));}I'm not getting any results when the pin is high or low, what have I done wrong?An unrelated question: When writing to a register requires synchronizing clocks, do I write to the register and then wait for the sync to complete or is the sync something I must instigate?this is what I thought I could do provided that it's the first optionCode:while(TC_STATUS_SYNCBUSY & (0x1u<<TC_STATUS_SYNCBUSY_Pos))// wait for sync to finish;Additionally, if anyone has a working library of functions and wants to share, that would be appreciated.

author: ataradov
author_rank: Super Contributor
timestamp: November 10, 2017, 04:17:31 am
content: Use this:https://github.com/ataradov/mcu-starter-projects/blob/master/samd10/hal_gpio.h, it works, it is small, it is tested.Don't worry about the synchronization for now.

author: n4alpaca
author_rank: Newbie
timestamp: November 10, 2017, 05:17:56 am
content: Thanks again Alex! you really seem to fielding all of the questions around here. I was asking about synchronizing clocks so that I could write idle delays and work with interrupts (timed and un-timed) through RTC and evsys. Is synchronizing not needed for those?

author: ataradov
author_rank: Super Contributor
timestamp: November 10, 2017, 05:22:02 am
content: Quote from: n4alpaca on November 10, 2017, 05:17:56 amSynchronizations is never required for writes. Your second write to the same register will stall the bus for a few cycles. This may matter for some applications, but if you are just learning, then it is probably not important.Some registers need read synchronizations to get correct value.But the general approach - don't think about the synchronization until you run into problems. This is not likely to happens for a very long time.