circuitpython/ports/stm32f4/common-hal/digitalio/DigitalInOut.c

159 lines
5.7 KiB
C
Raw Normal View History

2019-06-28 15:36:08 -04:00
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "py/runtime.h"
#include "supervisor/shared/translate.h"
2019-07-17 14:07:33 -04:00
#include "stm32f4xx_hal.h"
#include "stm32f4xx_ll_gpio.h"
2019-06-28 15:36:08 -04:00
void common_hal_digitalio_digitalinout_never_reset(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self) {
never_reset_pin_number(self->pin->port_number, self->pin->number);
2019-06-28 15:36:08 -04:00
}
digitalinout_result_t common_hal_digitalio_digitalinout_construct(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) {
claim_pin(pin);
self->pin = pin;
2019-06-28 15:36:08 -04:00
2019-07-17 14:07:33 -04:00
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = (1 << pin->number);
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(pin->port, &GPIO_InitStruct);
2019-06-28 15:36:08 -04:00
return DIGITALINOUT_OK;
}
bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) {
2019-07-17 14:07:33 -04:00
return self->pin == mp_const_none;
2019-06-28 15:36:08 -04:00
}
void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) {
2019-07-17 14:07:33 -04:00
if (common_hal_digitalio_digitalinout_deinited(self)) {
return;
}
2019-06-28 15:36:08 -04:00
2019-07-17 14:07:33 -04:00
reset_pin_number(self->pin->port_number, self->pin->number);
self->pin = mp_const_none;
2019-06-28 15:36:08 -04:00
}
void common_hal_digitalio_digitalinout_switch_to_input(
digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) {
2019-07-17 14:07:33 -04:00
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = (1 << self->pin->number);
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct);
2019-06-28 15:36:08 -04:00
common_hal_digitalio_digitalinout_set_pull(self, pull);
}
void common_hal_digitalio_digitalinout_switch_to_output(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self, bool value,
digitalio_drive_mode_t drive_mode) {
2019-06-28 15:36:08 -04:00
2019-07-17 14:07:33 -04:00
common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode);
common_hal_digitalio_digitalinout_set_value(self, value);
2019-06-28 15:36:08 -04:00
}
digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self) {
2019-06-28 15:36:08 -04:00
2019-07-17 14:07:33 -04:00
return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number))
== LL_GPIO_MODE_INPUT) ? DIRECTION_INPUT : DIRECTION_OUTPUT;
2019-06-28 15:36:08 -04:00
}
void common_hal_digitalio_digitalinout_set_value(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self, bool value) {
HAL_GPIO_WritePin(self->pin->port, 1 << self->pin->number, value);
2019-06-28 15:36:08 -04:00
}
bool common_hal_digitalio_digitalinout_get_value(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self) {
return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number)) == LL_GPIO_MODE_INPUT)
? HAL_GPIO_ReadPin(self->pin->port, (1 << self->pin->number))
: LL_GPIO_IsOutputPinSet(self->pin->port, (1 << self->pin->number));
2019-06-28 15:36:08 -04:00
}
void common_hal_digitalio_digitalinout_set_drive_mode(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self,
digitalio_drive_mode_t drive_mode) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = (1 << self->pin->number);
GPIO_InitStruct.Mode = (drive_mode == DRIVE_MODE_OPEN_DRAIN ?
GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT_PP);
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct);
2019-06-28 15:36:08 -04:00
}
digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self) {
return LL_GPIO_GetPinOutputType(self->pin->port, (1 << self->pin->port_number))
== LL_GPIO_OUTPUT_OPENDRAIN ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL;
2019-06-28 15:36:08 -04:00
}
void common_hal_digitalio_digitalinout_set_pull(
2019-07-17 14:07:33 -04:00
digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) {
switch (pull) {
case PULL_UP:
LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_UP);
break;
case PULL_DOWN:
LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_DOWN);
break;
case PULL_NONE:
LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_NO);
break;
default:
break;
}
2019-06-28 15:36:08 -04:00
}
digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
digitalio_digitalinout_obj_t *self) {
2019-07-17 14:07:33 -04:00
2019-06-28 15:36:08 -04:00
2019-07-17 14:07:33 -04:00
switch (LL_GPIO_GetPinPull(self->pin->port,(1 << self->pin->number))) {
case LL_GPIO_PULL_UP:
2019-06-28 15:36:08 -04:00
return PULL_UP;
2019-07-17 14:07:33 -04:00
case LL_GPIO_PULL_DOWN:
2019-06-28 15:36:08 -04:00
return PULL_DOWN;
2019-07-17 14:07:33 -04:00
case LL_GPIO_PULL_NO:
return PULL_NONE;
2019-06-28 15:36:08 -04:00
default:
return PULL_NONE;
}
}