Add shift register interface and improve LED integration with it
parent
c377674aee
commit
004db59da0
|
|
@ -187,6 +187,7 @@ target_sources(
|
||||||
PRIVATE src/main.cpp
|
PRIVATE src/main.cpp
|
||||||
src/hal/avr/cpu.cpp
|
src/hal/avr/cpu.cpp
|
||||||
src/hal/avr/usart.cpp
|
src/hal/avr/usart.cpp
|
||||||
|
src/hal/avr/shr16.cpp
|
||||||
src/hal/adc.cpp
|
src/hal/adc.cpp
|
||||||
src/modules/protocol.cpp
|
src/modules/protocol.cpp
|
||||||
src/modules/buttons.cpp
|
src/modules/buttons.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "../shr16.h"
|
||||||
|
#include "../gpio.h"
|
||||||
|
|
||||||
|
namespace hal {
|
||||||
|
namespace shr16 {
|
||||||
|
|
||||||
|
SHR16 shr16;
|
||||||
|
|
||||||
|
void SHR16::Init() {
|
||||||
|
// DDRC |= 0x80;
|
||||||
|
// DDRB |= 0x40;
|
||||||
|
// DDRB |= 0x20;
|
||||||
|
// PORTC &= ~0x80;
|
||||||
|
// PORTB &= ~0x40;
|
||||||
|
// PORTB &= ~0x20;
|
||||||
|
// shr16_v = 0;
|
||||||
|
// Write(shr16_v);
|
||||||
|
// Write(shr16_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHR16::Write(uint16_t v) {
|
||||||
|
// PORTB &= ~0x40;
|
||||||
|
// asm("nop");
|
||||||
|
// for (uint16_t m = 0x8000; m; m >>= 1)
|
||||||
|
// {
|
||||||
|
// if (m & v)
|
||||||
|
// PORTB |= 0x20;
|
||||||
|
// else
|
||||||
|
// PORTB &= ~0x20;
|
||||||
|
// PORTC |= 0x80;
|
||||||
|
// asm("nop");
|
||||||
|
// PORTC &= ~0x80;
|
||||||
|
// asm("nop");
|
||||||
|
// }
|
||||||
|
// PORTB |= 0x40;
|
||||||
|
// asm("nop");
|
||||||
|
// shr16_v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHR16::SetLED(uint16_t led) {
|
||||||
|
// led = ((led & 0x00ff) << 8) | ((led & 0x0300) >> 2);
|
||||||
|
// Write((shr16_v & ~SHR16_LED_MSK) | led);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHR16::SetTMCEnabled(uint8_t ena) {
|
||||||
|
// ena ^= 7;
|
||||||
|
// ena = ((ena & 1) << 1) | ((ena & 2) << 2) | ((ena & 4) << 3); // 0. << 1 == 1., 1. << 2 == 3., 2. << 3 == 5.
|
||||||
|
// Write((shr16_v & ~SHR16_ENA_MSK) | ena);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHR16::SetTMCDir(uint8_t dir) {
|
||||||
|
// dir = (dir & 1) | ((dir & 2) << 1) | ((dir & 4) << 2); // 0., 1. << 1 == 2., 2. << 2 == 4.
|
||||||
|
// Write((shr16_v & ~SHR16_DIR_MSK) | dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace shr16
|
||||||
|
} // namespace hal
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace hal {
|
||||||
|
namespace shr16 {
|
||||||
|
|
||||||
|
/// 16bit shift register (2x74595) interface
|
||||||
|
///
|
||||||
|
/// The pinout is hard coded as follows:
|
||||||
|
/// SHR16_CLK: signal d13 - PC7
|
||||||
|
/// SHR16_LAT: signal d10 - PB6
|
||||||
|
/// SHR16_DAT: signal d9 - PB5
|
||||||
|
///
|
||||||
|
/// Shift register outputs:
|
||||||
|
/// LEDS - hardcoded
|
||||||
|
/// SHR16_LEDG0 = 0x0100
|
||||||
|
/// SHR16_LEDR0 = 0x0200
|
||||||
|
/// SHR16_LEDG1 = 0x0400
|
||||||
|
/// SHR16_LEDR1 = 0x0800
|
||||||
|
/// SHR16_LEDG2 = 0x1000
|
||||||
|
/// SHR16_LEDR2 = 0x2000
|
||||||
|
/// SHR16_LEDG3 = 0x4000
|
||||||
|
/// SHR16_LEDR3 = 0x8000
|
||||||
|
/// SHR16_LEDG4 = 0x0040
|
||||||
|
/// SHR16_LEDR4 = 0x0080
|
||||||
|
/// SHR16_LED_MSK = 0xffc0
|
||||||
|
///
|
||||||
|
/// TMC2130 Direction/Enable signals - hardcoded
|
||||||
|
/// SHR16_DIR_0 = 0x0001
|
||||||
|
/// SHR16_ENA_0 = 0x0002
|
||||||
|
/// SHR16_DIR_1 = 0x0004
|
||||||
|
/// SHR16_ENA_1 = 0x0008
|
||||||
|
/// SHR16_DIR_2 = 0x0010
|
||||||
|
/// SHR16_ENA_2 = 0x0020
|
||||||
|
///
|
||||||
|
/// SHR16_DIR_MSK = (SHR16_DIR_0 + SHR16_DIR_1 + SHR16_DIR_2)
|
||||||
|
/// SHR16_ENA_MSK = (SHR16_ENA_0 + SHR16_ENA_1 + SHR16_ENA_2)
|
||||||
|
class SHR16 {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Init();
|
||||||
|
void SetLED(uint16_t led);
|
||||||
|
void SetTMCEnabled(uint8_t ena);
|
||||||
|
void SetTMCDir(uint8_t dir);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16_t shr16_v;
|
||||||
|
void Write(uint16_t v);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SHR16 shr16;
|
||||||
|
|
||||||
|
} // namespace shr16
|
||||||
|
} // namespace hal
|
||||||
49
src/main.cpp
49
src/main.cpp
|
|
@ -3,6 +3,7 @@
|
||||||
#include "hal/gpio.h"
|
#include "hal/gpio.h"
|
||||||
#include "hal/spi.h"
|
#include "hal/spi.h"
|
||||||
#include "hal/usart.h"
|
#include "hal/usart.h"
|
||||||
|
#include "hal/shr16.h"
|
||||||
|
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
@ -22,23 +23,23 @@ void TmpPlayground() {
|
||||||
using namespace hal;
|
using namespace hal;
|
||||||
|
|
||||||
// SPI example
|
// SPI example
|
||||||
gpio::Init(gpio::GPIO_pin(GPIOC, 6), gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high));
|
// gpio::Init(gpio::GPIO_pin(GPIOC, 6), gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high));
|
||||||
uint8_t dat[5];
|
// uint8_t dat[5];
|
||||||
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
|
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
|
||||||
spi::TxRx(SPI0, 0x01);
|
// spi::TxRx(SPI0, 0x01);
|
||||||
spi::TxRx(SPI0, 0x00);
|
// spi::TxRx(SPI0, 0x00);
|
||||||
spi::TxRx(SPI0, 0x00);
|
// spi::TxRx(SPI0, 0x00);
|
||||||
spi::TxRx(SPI0, 0x00);
|
// spi::TxRx(SPI0, 0x00);
|
||||||
spi::TxRx(SPI0, 0x00);
|
// spi::TxRx(SPI0, 0x00);
|
||||||
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
|
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
|
||||||
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
|
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
|
||||||
dat[0] = spi::TxRx(SPI0, 0x00);
|
// dat[0] = spi::TxRx(SPI0, 0x00);
|
||||||
dat[1] = spi::TxRx(SPI0, 0x00);
|
// dat[1] = spi::TxRx(SPI0, 0x00);
|
||||||
dat[2] = spi::TxRx(SPI0, 0x00);
|
// dat[2] = spi::TxRx(SPI0, 0x00);
|
||||||
dat[3] = spi::TxRx(SPI0, 0x00);
|
// dat[3] = spi::TxRx(SPI0, 0x00);
|
||||||
dat[4] = spi::TxRx(SPI0, 0x00);
|
// dat[4] = spi::TxRx(SPI0, 0x00);
|
||||||
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
|
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
|
||||||
(void)dat;
|
// (void)dat;
|
||||||
|
|
||||||
// using namespace hal::gpio;
|
// using namespace hal::gpio;
|
||||||
// WritePin(GPIO_pin(GPIOB, 5), Level::low);
|
// WritePin(GPIO_pin(GPIOB, 5), Level::low);
|
||||||
|
|
@ -68,9 +69,9 @@ void setup() {
|
||||||
|
|
||||||
cpu::Init();
|
cpu::Init();
|
||||||
|
|
||||||
// shr::Init()
|
shr16::shr16.Init();
|
||||||
leds.SetMode(4, false, modules::leds::Mode::blink0);
|
leds.SetMode(4, false, modules::leds::Mode::blink0);
|
||||||
// shr::Send(leds.Step(0));
|
leds.Step(0);
|
||||||
|
|
||||||
// @@TODO if the shift register doesn't work we really can't signalize anything, only internal variables will be accessible if the UART works
|
// @@TODO if the shift register doesn't work we really can't signalize anything, only internal variables will be accessible if the UART works
|
||||||
|
|
||||||
|
|
@ -81,7 +82,7 @@ void setup() {
|
||||||
};
|
};
|
||||||
hal::usart::usart1.Init(&usart_conf);
|
hal::usart::usart1.Init(&usart_conf);
|
||||||
leds.SetMode(3, false, modules::leds::Mode::on);
|
leds.SetMode(3, false, modules::leds::Mode::on);
|
||||||
// shr::Send(leds.Step(0));
|
leds.Step(0);
|
||||||
|
|
||||||
// @@TODO if both shift register and the UART are dead, we are sitting ducks :(
|
// @@TODO if both shift register and the UART are dead, we are sitting ducks :(
|
||||||
|
|
||||||
|
|
@ -96,15 +97,15 @@ void setup() {
|
||||||
};
|
};
|
||||||
spi::Init(SPI0, &spi_conf);
|
spi::Init(SPI0, &spi_conf);
|
||||||
leds.SetMode(2, false, modules::leds::Mode::on);
|
leds.SetMode(2, false, modules::leds::Mode::on);
|
||||||
//shr::Send(leds.Step(0));
|
leds.Step(0);
|
||||||
|
|
||||||
// tmc::Init()
|
// tmc::Init()
|
||||||
leds.SetMode(1, false, modules::leds::Mode::on);
|
leds.SetMode(1, false, modules::leds::Mode::on);
|
||||||
//shr::Send(leds.Step(0));
|
leds.Step(0);
|
||||||
|
|
||||||
// adc::Init();
|
// adc::Init();
|
||||||
leds.SetMode(0, false, modules::leds::Mode::on);
|
leds.SetMode(0, false, modules::leds::Mode::on);
|
||||||
//shr::Send(leds.Step(0));
|
leds.Step(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessRequestMsg(const modules::protocol::RequestMsg &rq) {
|
void ProcessRequestMsg(const modules::protocol::RequestMsg &rq) {
|
||||||
|
|
@ -149,7 +150,7 @@ void loop() {
|
||||||
ProcessRequestMsg(protocol.GetRequestMsg());
|
ProcessRequestMsg(protocol.GetRequestMsg());
|
||||||
}
|
}
|
||||||
buttons.Step(hal::adc::ReadADC(0));
|
buttons.Step(hal::adc::ReadADC(0));
|
||||||
// shr.Send(leds.Step(0));
|
leds.Step(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "leds.h"
|
#include "leds.h"
|
||||||
|
#include "hal/shr16.h"
|
||||||
|
|
||||||
namespace modules {
|
namespace modules {
|
||||||
namespace leds {
|
namespace leds {
|
||||||
|
|
@ -35,7 +36,7 @@ bool LED::Step(bool oddPeriod) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t LEDs::Step(uint8_t delta_ms) {
|
void LEDs::Step(uint8_t delta_ms) {
|
||||||
ms += delta_ms;
|
ms += delta_ms;
|
||||||
bool oddPeriod = ((ms / 1000U) & 0x01U) != 0;
|
bool oddPeriod = ((ms / 1000U) & 0x01U) != 0;
|
||||||
uint16_t result = 0;
|
uint16_t result = 0;
|
||||||
|
|
@ -43,7 +44,7 @@ uint16_t LEDs::Step(uint8_t delta_ms) {
|
||||||
result <<= 1;
|
result <<= 1;
|
||||||
result |= leds[i].Step(oddPeriod);
|
result |= leds[i].Step(oddPeriod);
|
||||||
}
|
}
|
||||||
return result;
|
hal::shr16::shr16.SetLED(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace leds
|
} // namespace leds
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,7 @@ public:
|
||||||
: ms(0) {};
|
: ms(0) {};
|
||||||
|
|
||||||
/// step LED automaton
|
/// step LED automaton
|
||||||
/// @returns statuses of LEDs - one bit per LED and 1 = on, 0 = off
|
void Step(uint8_t delta_ms);
|
||||||
uint16_t Step(uint8_t delta_ms);
|
|
||||||
|
|
||||||
inline constexpr uint8_t LedPairsCount() const { return ledPairs; }
|
inline constexpr uint8_t LedPairsCount() const { return ledPairs; }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue