Код:
// paddr = 0x42000000 + (0x40001000 + 0x0c * (ippin >> 5) - 0x40000000) * 32 + ((ippin & 0x1f) * 4);
paddr = BitBandPeriAddr((void *)(GPIO_REG_BASE + GPIO_PORTB_DR * (ippin >> 5)), ippin & 0x1f);
Это стеб такой?
-----
RTL00_WEB/bitband_io.c at 3e8794a4a369a11ca940d26cbf2a28c053428908 · pvvx/RTL00_WEB · GitHub
Тут вместо GPIO_PORTB_DR нужен GPIO_PORTB_DDR, и переименовать val в direction
Вы думаете, что я помню, что хотел там написать и как применить?
Данная функция была написана для неопубликованного драйвера RS-485 к Modbus для переключалки направления внешнего аппаратного драйвера
rs485cfg.bitband_dir = HardSetPin(PC_0, PIN_OUTPUT, PullNone, 1);
А в указанном на git остался какой-то другой вариант для чего-то другого...
Есть и такой вариант, в моих тестах:
Код:
volatile u8 * HardSetPin(PinName pin, PinDirection pdir, PinMode pmode, u8 val)
{
volatile u8 *paddr = NULL;
u32 ippin = HAL_GPIO_GetIPPinName_8195a(pin);
if(ippin != 0xff) {
// paddr = 0x42000000 + (0x40001000 + 0x0c * (ippin >> 5) - 0x40000000) * 32 + ((ippin & 0x1f) * 4);
paddr = BitBandPeriAddr((void *)(GPIO_REG_BASE + GPIO_PORTB_DR * (ippin >> 5)), ippin & 0x1f);
}
if(paddr && _pHAL_Gpio_Adapter) {
if (_pHAL_Gpio_Adapter->Gpio_Func_En == 0) GPIO_FuncOn_8195a();
paddr[0] = val; // data register
paddr[(GPIO_PORTB_DDR - GPIO_PORTB_DR) * 32] = pdir; // data direction
#if 1 // if use HAL_Gpio_Adapter
uint32 * p = &_pHAL_Gpio_Adapter->Local_Gpio_Dir[ippin >> 5];
if(pdir) *p |= 1 << (ippin & 0x1f);
else *p &= ~(1 << (ippin & 0x1f));
#endif
paddr[(GPIO_PORTB_CTRL - GPIO_PORTB_DR) * 32] = 0; // data source control, we should keep it as default: data source from software
HAL_GPIO_PullCtrl_8195a(pin, pmode); // set GPIO_PULL_CTRLx
}
return paddr;
}
По мере отладки и проверок на разные потребности он ещё будет меняться и дополняться...
В моих примерах кинутых на git данная функция пока не используется.
А что там вам там не понравилось?
GPIO_PORTX_DR -> 0x40001000 и в него задается значение, а установка direction - это другой порт, используется через ROM-BIOS функцию, для связи переменных ROM-BIOS.
И HardSetPin() в моем варианте не должен управлять direction для всех случаев.
Пример с открытым коллектором. Направлением direction пина и производится переключение "0" и "1" на выводе...
Может вы попутали всё с Arduino? Это только в Arduino пин в режиме "открытый коллектор" инвертируется в больную и нереальную для работающих с электроникой ситуацию, но заученную "домочадцами" на основании виртуального, а не физического значения на пине.
При выводе "1" на пине будет "0"
При выводе и чтении в Arduino в порт с OK соответствия с тестером нет, как есть и неопределенность - что даст их любимая функция получения напряжения с пина, имеющего 3 состояния
Так-же, перед тем как менять direction порта, надо-бы установить выводимое значение, а не устраивать неопределенности и выплески на пине c неизвестным предыдущим записанным туда значением
А HardSetPin - это всего инициализация порта, без установки direction. После неё будет пин в input.