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
src/hal/avr/cpu.cpp
src/hal/avr/usart.cpp
src/hal/avr/shr16.cpp
src/hal/adc.cpp
src/modules/protocol.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/spi.h"
#include "hal/usart.h"
#include "hal/shr16.h"
#include "pins.h"
#include <avr/interrupt.h>
@ -22,23 +23,23 @@ void TmpPlayground() {
using namespace hal;
// SPI example
gpio::Init(gpio::GPIO_pin(GPIOC, 6), gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high));
uint8_t dat[5];
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
spi::TxRx(SPI0, 0x01);
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::low);
dat[0] = spi::TxRx(SPI0, 0x00);
dat[1] = spi::TxRx(SPI0, 0x00);
dat[2] = spi::TxRx(SPI0, 0x00);
dat[3] = spi::TxRx(SPI0, 0x00);
dat[4] = spi::TxRx(SPI0, 0x00);
gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
(void)dat;
// gpio::Init(gpio::GPIO_pin(GPIOC, 6), gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high));
// uint8_t dat[5];
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::low);
// spi::TxRx(SPI0, 0x01);
// 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::low);
// dat[0] = spi::TxRx(SPI0, 0x00);
// dat[1] = spi::TxRx(SPI0, 0x00);
// dat[2] = spi::TxRx(SPI0, 0x00);
// dat[3] = spi::TxRx(SPI0, 0x00);
// dat[4] = spi::TxRx(SPI0, 0x00);
// gpio::WritePin(gpio::GPIO_pin(GPIOC, 6), gpio::Level::high);
// (void)dat;
// using namespace hal::gpio;
// WritePin(GPIO_pin(GPIOB, 5), Level::low);
@ -68,9 +69,9 @@ void setup() {
cpu::Init();
// shr::Init()
shr16::shr16.Init();
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
@ -81,7 +82,7 @@ void setup() {
};
hal::usart::usart1.Init(&usart_conf);
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 :(
@ -96,15 +97,15 @@ void setup() {
};
spi::Init(SPI0, &spi_conf);
leds.SetMode(2, false, modules::leds::Mode::on);
//shr::Send(leds.Step(0));
leds.Step(0);
// tmc::Init()
leds.SetMode(1, false, modules::leds::Mode::on);
//shr::Send(leds.Step(0));
leds.Step(0);
// adc::Init();
leds.SetMode(0, false, modules::leds::Mode::on);
//shr::Send(leds.Step(0));
leds.Step(0);
}
void ProcessRequestMsg(const modules::protocol::RequestMsg &rq) {
@ -149,7 +150,7 @@ void loop() {
ProcessRequestMsg(protocol.GetRequestMsg());
}
buttons.Step(hal::adc::ReadADC(0));
// shr.Send(leds.Step(0));
leds.Step(0);
}
int main() {

View File

@ -1,4 +1,5 @@
#include "leds.h"
#include "hal/shr16.h"
namespace modules {
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;
bool oddPeriod = ((ms / 1000U) & 0x01U) != 0;
uint16_t result = 0;
@ -43,7 +44,7 @@ uint16_t LEDs::Step(uint8_t delta_ms) {
result <<= 1;
result |= leds[i].Step(oddPeriod);
}
return result;
hal::shr16::shr16.SetLED(result);
}
} // namespace leds

View File

@ -51,8 +51,7 @@ public:
: ms(0) {};
/// step LED automaton
/// @returns statuses of LEDs - one bit per LED and 1 = on, 0 = off
uint16_t Step(uint8_t delta_ms);
void Step(uint8_t delta_ms);
inline constexpr uint8_t LedPairsCount() const { return ledPairs; }