Add shift register interface and improve LED integration with it

pull/13/head
D.R.racer 2021-05-26 09:29:32 +02:00
parent c377674aee
commit 004db59da0
6 changed files with 142 additions and 28 deletions

View File

@ -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

57
src/hal/avr/shr16.cpp Normal file
View File

@ -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

55
src/hal/shr16.h Normal file
View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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; }