microwire_master: minor, use simpler GPIO definitions

This commit is contained in:
King Kévin 2020-02-17 14:04:41 +01:00
parent 330a08adc0
commit 0454647d2d
2 changed files with 32 additions and 35 deletions

View File

@ -12,10 +12,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/** library to communicate using microwore as master (code) /** library to communicate using microwore as master
* @file microwire_master.c * @file
* @author King Kévin <kingkevin@cuvoodoo.info> * @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017 * @date 2017-2020
* @note peripherals used: GPIO @ref microwire_master_gpio, timer @ref microwire_master_timer * @note peripherals used: GPIO @ref microwire_master_gpio, timer @ref microwire_master_timer
* microwire is a 3-Wire half-duplex synchronous bus. It is very similar to SPI without fixed length messages (bit-wised). * microwire is a 3-Wire half-duplex synchronous bus. It is very similar to SPI without fixed length messages (bit-wised).
* @note the user has to handle the slave select pin (high during operations) so to be able to handle multiple slaves. * @note the user has to handle the slave select pin (high during operations) so to be able to handle multiple slaves.
@ -38,12 +38,9 @@
/** @defgroup microwire_master_gpio GPIO peripheral used to communicate /** @defgroup microwire_master_gpio GPIO peripheral used to communicate
* @{ * @{
*/ */
#define MICROWIRE_MASTER_SDO_PORT A /**< SDO output signal port (to be connected on D slave signal) */ #define MICROWIRE_MASTER_SDO_PIN PA0 /**< SDO output signal pin (to be connected on D slave signal) */
#define MICROWIRE_MASTER_SDO_PIN 0 /**< SDO output signal pin (to be connected on D slave signal) */ #define MICROWIRE_MASTER_SDI_PIN PA2 /**< SDO input signal pin (to be connected on Q slave signal) */
#define MICROWIRE_MASTER_SDI_PORT A /**< SDO input signal port (to be connected on Q slave signal) */ #define MICROWIRE_MASTER_SCK_PIN PA4 /**< SCK output signal pin (to be connected on C slave signal) */
#define MICROWIRE_MASTER_SDI_PIN 2 /**< SDO input signal pin (to be connected on Q slave signal) */
#define MICROWIRE_MASTER_SCK_PORT A /**< SCK output signal port (to be connected on C slave signal) */
#define MICROWIRE_MASTER_SCK_PIN 4 /**< SCK output signal pin (to be connected on C slave signal) */
/** @} */ /** @} */
/** @defgroup microwire_master_timer timer peripheral used to generate timing for the signal /** @defgroup microwire_master_timer timer peripheral used to generate timing for the signal
@ -67,14 +64,14 @@ void microwire_master_setup(uint32_t frequency, bool organization_x16, uint8_t a
mirowire_master_organization_x16 = organization_x16; // save organisation mirowire_master_organization_x16 = organization_x16; // save organisation
// setup GPIO // setup GPIO
rcc_periph_clock_enable(RCC_GPIO(MICROWIRE_MASTER_SDO_PORT)); // enable clock for GPIO domain for SDO signal rcc_periph_clock_enable(GPIO_RCC(MICROWIRE_MASTER_SDO_PIN)); // enable clock for GPIO domain for SDO signal
gpio_set_mode(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MICROWIRE_MASTER_SDO_PIN)); // set SDO signal as output (controlled by the master) gpio_set_mode(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // set SDO signal as output (controlled by the master)
gpio_clear(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(MICROWIRE_MASTER_SDO_PIN)); // SDO is idle low gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // SDO is idle low
rcc_periph_clock_enable(RCC_GPIO(MICROWIRE_MASTER_SDI_PORT)); // enable clock for GPIO domain for SDI signal rcc_periph_clock_enable(GPIO_RCC(MICROWIRE_MASTER_SDI_PIN)); // enable clock for GPIO domain for SDI signal
gpio_set_mode(GPIO(MICROWIRE_MASTER_SDI_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(MICROWIRE_MASTER_SDI_PIN)); // set SDI signal as output (controlled by the slave) gpio_set_mode(GPIO_PORT(MICROWIRE_MASTER_SDI_PIN), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_PIN(MICROWIRE_MASTER_SDI_PIN)); // set SDI signal as output (controlled by the slave)
rcc_periph_clock_enable(RCC_GPIO(MICROWIRE_MASTER_SCK_PORT)); // enable clock for GPIO domain for SCK signal rcc_periph_clock_enable(GPIO_RCC(MICROWIRE_MASTER_SCK_PIN)); // enable clock for GPIO domain for SCK signal
gpio_set_mode(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MICROWIRE_MASTER_SCK_PIN)); // set SCK signal as output (controlled by the master) gpio_set_mode(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // set SCK signal as output (controlled by the master)
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // SCK is idle low gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // SCK is idle low
// setup timer to generate timing for the signal // setup timer to generate timing for the signal
rcc_periph_clock_enable(RCC_TIM(MICROWIRE_MASTER_TIMER)); // enable clock for timer domain rcc_periph_clock_enable(RCC_TIM(MICROWIRE_MASTER_TIMER)); // enable clock for timer domain
@ -105,14 +102,14 @@ static void microwire_master_wait_clock(void)
static void microwire_master_send_bit(bool bit) static void microwire_master_send_bit(bool bit)
{ {
if (bit) { if (bit) {
gpio_set(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(MICROWIRE_MASTER_SDO_PIN)); // set '1' on output gpio_set(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // set '1' on output
} else { } else {
gpio_clear(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(MICROWIRE_MASTER_SDO_PIN)); // set '0' on output gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // set '0' on output
} }
microwire_master_wait_clock(); // wait for clock timing microwire_master_wait_clock(); // wait for clock timing
gpio_set(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // make rising edge for slave to sample gpio_set(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // make rising edge for slave to sample
microwire_master_wait_clock(); // keep output signal stable while clock is high microwire_master_wait_clock(); // keep output signal stable while clock is high
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // put clock back to idle gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // put clock back to idle
} }
/** initialize microwire communication and send header (with leading start bit '1') /** initialize microwire communication and send header (with leading start bit '1')
@ -127,8 +124,8 @@ static void microwire_master_start(uint8_t operation, uint32_t address)
} }
// initial setup // initial setup
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge) gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter timer_set_counter(TIM(MICROWIRE_MASTER_TIMER), 0); // reset timer counter
timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag
nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag (else event doesn't wake up) nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag (else event doesn't wake up)
timer_enable_counter(TIM(MICROWIRE_MASTER_TIMER)); // start timer to generate timing timer_enable_counter(TIM(MICROWIRE_MASTER_TIMER)); // start timer to generate timing
@ -155,7 +152,7 @@ static void microwire_master_start(uint8_t operation, uint32_t address)
microwire_master_send_bit(false); // send '0' address bit microwire_master_send_bit(false); // send '0' address bit
} }
} }
gpio_clear(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(MICROWIRE_MASTER_SDO_PIN)); // ensure output is idle low (could be floating) gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // ensure output is idle low (could be floating)
} }
/** stop microwire communication and end all activities */ /** stop microwire communication and end all activities */
@ -165,8 +162,8 @@ static void microwire_master_stop(void)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter
timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag
nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is idle low gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is idle low
gpio_clear(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(MICROWIRE_MASTER_SDO_PIN)); // ensure output is idle low gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // ensure output is idle low
} }
@ -176,10 +173,10 @@ static void microwire_master_stop(void)
static bool microwire_master_read_bit(void) static bool microwire_master_read_bit(void)
{ {
microwire_master_wait_clock(); // wait for clock timing microwire_master_wait_clock(); // wait for clock timing
gpio_set(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // make rising edge for slave to output data gpio_set(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // make rising edge for slave to output data
microwire_master_wait_clock(); // wait for signal to be stable microwire_master_wait_clock(); // wait for signal to be stable
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // set clock low again gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // set clock low again
return 0!=gpio_get(GPIO(MICROWIRE_MASTER_SDI_PORT), GPIO(MICROWIRE_MASTER_SDI_PIN)); // read input signal return 0 != gpio_get(GPIO_PORT(MICROWIRE_MASTER_SDI_PIN), GPIO_PIN(MICROWIRE_MASTER_SDI_PIN)); // read input signal
} }
void microwire_master_read(uint32_t address, uint16_t* data, size_t length) void microwire_master_read(uint32_t address, uint16_t* data, size_t length)
@ -192,7 +189,7 @@ void microwire_master_read(uint32_t address, uint16_t* data, size_t length)
microwire_master_start(0x02, address); // send '10' READ instruction and memory address microwire_master_start(0x02, address); // send '10' READ instruction and memory address
// there should already be a '0' dummy bit // there should already be a '0' dummy bit
if (0!=gpio_get(GPIO(MICROWIRE_MASTER_SDI_PORT), GPIO(MICROWIRE_MASTER_SDI_PIN))) { // the dummy bit wasn't '0' if (0!=gpio_get(GPIO_PORT(MICROWIRE_MASTER_SDI_PIN), GPIO_PIN(MICROWIRE_MASTER_SDI_PIN))) { // the dummy bit wasn't '0'
goto clean; goto clean;
} }
@ -258,8 +255,8 @@ void microwire_master_wait_ready(void)
{ {
// initial setup // initial setup
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge) gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter timer_set_counter(TIM(MICROWIRE_MASTER_TIMER), 0); // reset timer counter
timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag timer_clear_flag(TIM(MICROWIRE_MASTER_TIMER), TIM_SR_UIF); // clear timer flag
nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag (else event doesn't wake up) nvic_clear_pending_irq(NVIC_TIM_IRQ(MICROWIRE_MASTER_TIMER)); // clear IRQ flag (else event doesn't wake up)
timer_enable_counter(TIM(MICROWIRE_MASTER_TIMER)); // start timer to generate timing timer_enable_counter(TIM(MICROWIRE_MASTER_TIMER)); // start timer to generate timing

View File

@ -12,10 +12,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/** library to communicate using microwore as master (API) /** library to communicate using microwore as master
* @file microwire_master.h * @file
* @author King Kévin <kingkevin@cuvoodoo.info> * @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017 * @date 2017-2020
* @note peripherals used: GPIO @ref microwire_master_gpio, timer @ref microwire_master_timer * @note peripherals used: GPIO @ref microwire_master_gpio, timer @ref microwire_master_timer
* microwire is a 3-Wire half-duplex synchronous bus. It is very similar to SPI without fixed length messages (bit-wised). * microwire is a 3-Wire half-duplex synchronous bus. It is very similar to SPI without fixed length messages (bit-wised).
* @note the user has to handle the slave select pin (high during operations) so to be able to handle multiple slaves. * @note the user has to handle the slave select pin (high during operations) so to be able to handle multiple slaves.