Hello, I've been struggling with getting digital read to work.
This is how the code flows
Pin initialization:
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 MASK
if(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 MASK
if(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 input
PORT->Group->DIRSET.reg = (p.dir << ( p.pinNum ));
// end set output
// set input
WRCONFIG += (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 enable
if(p.pull != NO_PULL){
WRCONFIG += (p.pull << PORT_WRCONFIG_PULLEN_Pos ); // if it's an output, this is a "don't care condition
PORT->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.
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 option
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.