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/>.
*
*/
/** library to communicate using microwore as master (code)
* @file microwire_master.c
/** library to communicate using microwore as master
* @file
* @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
* 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.
@ -38,12 +38,9 @@
/** @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 0 /**< SDO output signal pin (to be connected on D slave signal) */
#define MICROWIRE_MASTER_SDI_PORT A /**< SDO input signal port (to be connected on Q 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) */
#define MICROWIRE_MASTER_SDO_PIN PA0 /**< 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_SCK_PIN PA4 /**< SCK output signal pin (to be connected on C slave 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
// setup GPIO
rcc_periph_clock_enable(RCC_GPIO(MICROWIRE_MASTER_SDO_PORT)); // 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_clear(GPIO(MICROWIRE_MASTER_SDO_PORT), GPIO(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
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)
rcc_periph_clock_enable(RCC_GPIO(MICROWIRE_MASTER_SCK_PORT)); // 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_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // SCK is idle low
rcc_periph_clock_enable(GPIO_RCC(MICROWIRE_MASTER_SDO_PIN)); // enable clock for GPIO domain for SDO signal
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_PORT(MICROWIRE_MASTER_SDO_PIN), GPIO_PIN(MICROWIRE_MASTER_SDO_PIN)); // SDO is idle low
rcc_periph_clock_enable(GPIO_RCC(MICROWIRE_MASTER_SDI_PIN)); // enable clock for GPIO domain for SDI signal
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(GPIO_RCC(MICROWIRE_MASTER_SCK_PIN)); // enable clock for GPIO domain for SCK signal
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_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // SCK is idle low
// setup timer to generate timing for the signal
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)
{
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 {
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
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
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')
@ -127,8 +124,8 @@ static void microwire_master_start(uint8_t operation, uint32_t address)
}
// initial setup
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter
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_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)
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
}
}
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 */
@ -165,8 +162,8 @@ static void microwire_master_stop(void)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter
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
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(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_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // ensure clock 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)
{
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
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(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
gpio_clear(GPIO_PORT(MICROWIRE_MASTER_SCK_PIN), GPIO_PIN(MICROWIRE_MASTER_SCK_PIN)); // set clock low again
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)
@ -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
// 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;
}
@ -258,8 +255,8 @@ void microwire_master_wait_ready(void)
{
// initial setup
gpio_clear(GPIO(MICROWIRE_MASTER_SCK_PORT), GPIO(MICROWIRE_MASTER_SCK_PIN)); // ensure clock is low (to sample on rising edge)
timer_set_counter(TIM(MICROWIRE_MASTER_TIMER),0); // reset timer counter
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_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)
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/>.
*
*/
/** library to communicate using microwore as master (API)
* @file microwire_master.h
/** library to communicate using microwore as master
* @file
* @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
* 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.