Skip to content

Commit

Permalink
add STM32F401 (black pill) and APA102
Browse files Browse the repository at this point in the history
  • Loading branch information
Wouter van Ooijen committed Nov 17, 2021
1 parent 1e56f14 commit 62a3098
Show file tree
Hide file tree
Showing 10 changed files with 906 additions and 11 deletions.
13 changes: 8 additions & 5 deletions library/core/hwlib-servo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ namespace hwlib {

/// properties of a servo
///
/// This struct stores the properties of an (individual) servo.
/// This struct stores the properties of an (individual) servo:
/// - the range (angle) over which the shaft can rotate (in degrees)
/// - the pulse widths that corresponds to this range
///
/// The defaults values are 0..180 degrees and 500 .. 2500 uS.
struct servo_properties {

/// the minimum pulse duration
Expand Down Expand Up @@ -187,7 +191,7 @@ servo_dummy_t servo_dummy;
/// constructor function invert().
class servo_invert_t : public servo {
private:

servo & minion;

public:
Expand Down Expand Up @@ -233,7 +237,7 @@ servo_invert_t invert( servo & s ){
/// constructor function all().
class servo_all_t : public servo {
private:

static constexpr int max_servos = 16;
servo * servos[ max_servos ];

Expand Down Expand Up @@ -261,7 +265,7 @@ class servo_all_t : public servo {
):
servo( properties ),
servos {
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7,
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7,
&p8, &p9, &p10, &p11, &p12, &p13, &p14, &p15
}{}

Expand Down Expand Up @@ -324,5 +328,4 @@ servo_all_t all(

#endif // _HWLIB_ONCE


}; // namespace hwlib
1 change: 1 addition & 0 deletions library/core/hwlib-targets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum class target_chips {
atmega328p,
atsam3x8e,
stm32f103c8,
stm32f401cc,
gd32vf103c8
};

Expand Down
1 change: 1 addition & 0 deletions library/hwlib-all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#include HWLIB_INCLUDE( peripherals/hwlib-hd44780.hpp )
#include HWLIB_INCLUDE( peripherals/hwlib-glcd-5510.hpp )
#include HWLIB_INCLUDE( peripherals/hwlib-glcd-oled.hpp )
#include HWLIB_INCLUDE( peripherals/hwlib-apa102.hpp )
#ifndef __AVR__
#include HWLIB_INCLUDE( peripherals/hwlib-glcd-st7789.hpp )
#endif
Expand Down
5 changes: 5 additions & 0 deletions library/hwlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@
#include HWLIB_INCLUDE( targets/hwlib-stm32f103c8.hpp )
#endif

#ifdef HWLIB_TARGET_stm32f401cc
#define HWLIB_TARGET
#include HWLIB_INCLUDE( targets/hwlib-stm32f401cc.hpp )
#endif

#ifdef BMPTK_TARGET_scouting_lock
#define HWLIB_TARGET
#include HWLIB_INCLUDE( hwlib-scouting-lock.hpp )
Expand Down
97 changes: 97 additions & 0 deletions library/peripherals/hwlib-apa102.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// ==========================================================================
//
// File : hwlib-apa102.hpp
// Part of : C++ hwlib library for close-to-the-hardware OO programming
// Copyright : wouter@voti.nl 2021
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// ==========================================================================

// included only via hwlib.hpp, hence no multiple-include guard is needed

// this file contains Doxygen lines
/// @file

namespace hwlib {


/// \brief
/// APA102 RGB LED strip
/// \details
/// This class template implements an interface to a strip
/// of APA102 GRB LEDs.
///
/// The template parameter is the number of LEDs in the strip.
///
/// The interface is buffered: all writes
/// are buffered in memory until flush() is called.
///
/// The strip must be powered with 5V.
/// Take care: the current for one LED fully on is 60 mA.
/// For a strip of more than say 10 LEDs you need to take precausions
/// for the current.
///
/// In my experience the digital inputs of an APA102 can be
/// driven by 3.3V GPIO pins.


// ==========================================================================
//
// apa102
//
// ==========================================================================

template< int n >
class apa102 : public window {
private:
pin_out & ci;
pin_out & di;
std::array< hwlib::color, n > pixels;

void write_byte( uint8_t b ){
for( int i = 0; i < 8; ++i ){
hwlib::wait_us( 1 );
di.write( ( b & 0x80 ) != 0 ); di.flush();
b = b << 1;
ci.write( 0 ); ci.flush();
hwlib::wait_us( 1 );
ci.write( 1 ); ci.flush();
hwlib::wait_us( 1 );
}
}

void write_word( uint32_t w ){
write_byte( w >> 24 );
write_byte( w >> 16 );
write_byte( w >> 8 );
write_byte( w >> 0 );
}

void write_implementation(
xy pos,
color col
) override {
pixels[ pos.x ] = col;
}

public:
apa102( pin_out & ci, pin_out & di ):
window( xy( n, 1 ) ), ci( ci ), di( di )
{}

void flush() override {
write_word( 0x00000000 );
for( auto c : pixels ){
write_byte( 0xFF );
write_byte( c.blue );
write_byte( c.green );
write_byte( c.red );
}
write_word( 0xFFFFFFFF );
}
};

}; // namespace hwlib
2 changes: 1 addition & 1 deletion library/targets/hwlib-arduino-due.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ const HWLIB_WEAK pin_info_type & pin_info( pins name ){
/// \endcond


/// Arduino Due pin names
/// Arduino Due ADC pin names
///
/// These are the ADC pins of an Arduino Due board.
enum class ad_pins {
Expand Down
10 changes: 5 additions & 5 deletions library/targets/hwlib-stm32f1xx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
#include HWLIB_INCLUDE(../hwlib-all.hpp)

// the STM header files use 'register' in the pre-C++17 sense
//#define register
#define register
#include "stm32f103xb.h"
//#undef register
#undef register

/// \brief
/// hwlib HAL for the stm32f1xx chips
Expand Down Expand Up @@ -322,11 +322,11 @@ namespace stm32f1xx {
}

if (data_in != nullptr) {
while (!SPI1->SR & SPI_SR_RXNE) { //Wait for byte to be received
while (! (SPI1->SR & SPI_SR_RXNE) ) { //Wait for byte to be received
hwlib::wait_ns_busy(1);
}
data_in[i] = SPI1->DR;
*data_in++;
*data_in = SPI1->DR;
data_in++;
}
}
}
Expand Down
145 changes: 145 additions & 0 deletions library/targets/hwlib-stm32f401cc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// ==========================================================================
//
// File : hwlib-stm32f401cc.hpp
// Part of : C++ hwlib library for close-to-the-hardware OO programming
// Copyright : wouter@voti.nl 2021
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// ==========================================================================


#ifndef HWLIB_STM32F401CC_H
#define HWLIB_STM32F401CC_H

#include HWLIB_INCLUDE(../hwlib-all.hpp)

namespace stm32f4xx {

/// GPIO pin names
enum class pins {
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15,
c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15,
led,
/// \cond INTERNAL
SIZE_THIS_IS_NOT_A_PIN
/// \endcond
};

/// \cond INTERNAL
struct pin_info_type {
uint8_t port;
uint8_t pin;
};

const HWLIB_WEAK pin_info_type &pin_info(pins name) {

static const pin_info_type pin_info_array[(int) pins::SIZE_THIS_IS_NOT_A_PIN] = {
{ 0, 0 }, // a0
{ 0, 1 }, // a1
{ 0, 2 }, // a2
{ 0, 3 }, // a3
{ 0, 4 }, // a4
{ 0, 5 }, // a5
{ 0, 6 }, // a6
{ 0, 7 }, // a7

{ 0, 8 }, // a8
{ 0, 9 }, // a9
{ 0, 10 }, // a10
{ 0, 11 }, // a11
{ 0, 12 }, // a12
{ 0, 13 }, // a13
{ 0, 14 }, // a14
{ 0, 15 }, // a15

{ 1, 0 }, // b0
{ 1, 1 }, // b1
{ 1, 2 }, // b2
{ 1, 3 }, // b3
{ 1, 4 }, // b4
{ 1, 5 }, // b5
{ 1, 6 }, // b6
{ 1, 7 }, // b7

{ 1, 8 }, // b8
{ 1, 9 }, // b9
{ 1, 10 }, // b10
{ 1, 11 }, // b11
{ 1, 12 }, // b12
{ 1, 13 }, // b13
{ 1, 14 }, // b14
{ 1, 15 }, // b15

{ 2, 0 }, // c0
{ 2, 1 }, // c1
{ 2, 2 }, // c2
{ 2, 3 }, // c3
{ 2, 4 }, // c4
{ 2, 5 }, // c5
{ 2, 6 }, // c6
{ 2, 7 }, // c7

{ 2, 8 }, // c8
{ 2, 9 }, // c9
{ 2, 10 }, // c10
{ 2, 11 }, // c11
{ 2, 12 }, // c12
{ 2, 13 }, // c13
{ 2, 14 }, // c14
{ 2, 15 }, // c15

{ 2, 13 }, // led

};

uint_fast8_t n = static_cast< uint_fast8_t>( name );
if (n >= static_cast< uint_fast8_t>( pins::SIZE_THIS_IS_NOT_A_PIN )) {
HWLIB_PANIC_WITH_LOCATION;
}
return pin_info_array[ n ];

}

/// STM32F401cc ADC pins
///
/// These are the ADC pins of the STM32F401cc chip.
/// The names are the GPIO names (b0 etc.),
/// not the AD channel names (ADC_IN8 etc.)
enum class ad_pins {

a0 = 0,
a1 = 1,
a2 = 2,
a3 = 3,
a4 = 4,
a5 = 5,
a6 = 6,
a7 = 7,
b0 = 8,
b1 = 9,
c0 = 10,
c1 = 11,
c2 = 12,
c3 = 13
};

/// \endcond

}; // end namespace stm32f4xx

#include HWLIB_INCLUDE( hwlib-stm32f4xx.hpp )

namespace stm32f401cc = ::stm32f4xx;

namespace hwlib {

namespace target = ::stm32f401cc;
const auto target_chip = target_chips::stm32f401cc;

};

#endif // #ifdef HWLIB_STM32F401CC_H
Loading

0 comments on commit 62a3098

Please sign in to comment.