commit 7d10a1e8c93af788094d62b6411367752022c039 Author: Eduardo Silva Date: Sun Sep 28 21:13:08 2025 +0100 First commit with SRs 165N and 595N functionality diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8ac1ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.clang_complete +.gcc-flags.json +.ccls +.cache +compile_commands.json diff --git a/165_pinout.webp b/165_pinout.webp new file mode 100644 index 0000000..fb4e7fb Binary files /dev/null and b/165_pinout.webp differ diff --git a/595n_pinout.webp b/595n_pinout.webp new file mode 100644 index 0000000..d88ade9 Binary files /dev/null and b/595n_pinout.webp differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..632bc85 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +# Uncomment lines below if you have problems with $PATH +#SHELL := /bin/bash +#PATH := /usr/local/bin:$(PATH) + +all: + pio -f -c vim run + +upload: + pio -f -c vim run --target upload + +clean: + pio -f -c vim run --target clean + +program: + pio -f -c vim run --target program + +uploadfs: + pio -f -c vim run --target uploadfs + +update: + pio -f -c vim update + diff --git a/check.py b/check.py new file mode 100644 index 0000000..fc99ab3 --- /dev/null +++ b/check.py @@ -0,0 +1,50 @@ +#!/bin/env python + +import sys +import time +Import("env") + + +# print("\n\nCurrent CLI targets:", COMMAND_LINE_TARGETS) +# print("Current Build targets:\n", BUILD_TARGETS) + + +def check_ram_usage(target, source, env): + memory_stats = env["PROGNAME"] + ".map" + map_file = env.subst("$BUILD_DIR/") + memory_stats + + # print("\n\nmemory_stats: %s" % memory_stats) + # print("map_file: %s\n" % map_file) + + try: + content = {} + with open(map_file, "r") as file: + content = file.read() + + memZones = (".bss", ".noinit", ".data") + ram_usage = 0 + for line in content.splitlines(): + if not line.startswith(memZones): + continue + + pp = line.split() + size = 0 + size = int(pp[2], 0) + + ram_usage += size + + ram_perc = (ram_usage / int(env.GetProjectOption("max_ram")) * 100) + print("RAM USAGE: %d / %d [%.2f%%]" % + (ram_usage, int(env.GetProjectOption("max_ram")), ram_perc)) + print("FLASH FLASH: N/A / %d" % int(env.GetProjectOption("max_flash"))) + + if ram_perc > float(env.GetProjectOption("max_ram_perc")): + print("RAM USAGE EXCEEDS LIMIT") + sys.exit(1) + + except FileNotFoundError: + print("Coult not find map_file %s" % map_file) + sys.exit(1) + + +env.AddPreAction("upload", check_ram_usage) diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..e3950a5 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,21 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:sparkfun_promicro16] +platform = atmelavr +board = sparkfun_promicro16 +framework = arduino +# upload_port = /dev/ttyACM0 +build_flags = -Wl,-Map=${BUILD_DIR}/${PROGNAME}.map +extra_scripts = post:check.py +max_ram = 2560 +max_ram_perc = 80 +max_flash = 28672 +max_flash_perc = 90 diff --git a/src/165.cpp b/src/165.cpp new file mode 100644 index 0000000..6d5deaa --- /dev/null +++ b/src/165.cpp @@ -0,0 +1,35 @@ +#include "Arduino.h" +#include +#include "165.h" + +SR165 NewSR165(uint8_t pl, uint8_t ce, uint8_t cp, uint8_t q7) { + SR165 newSr = { + .parallelLoadIn = pl, + .clockEnable = ce, + .complementaryOut = q7, + .clockIn = cp + }; + + pinMode(newSr.clockIn, OUTPUT); + pinMode(newSr.clockEnable, OUTPUT); + pinMode(newSr.parallelLoadIn, OUTPUT); + pinMode(newSr.complementaryOut, INPUT); + + return newSr; +} + +byte SR165_read(SR165 *sr) { + // Write pulse to load pin + digitalWrite(sr->parallelLoadIn, LOW); + delayMicroseconds(5); + digitalWrite(sr->parallelLoadIn, HIGH); + delayMicroseconds(5); + + // Get data from 74HC165 + digitalWrite(sr->clockIn, HIGH); + digitalWrite(sr->clockEnable, LOW); + byte incoming = shiftIn(sr->complementaryOut, sr->clockIn, LSBFIRST); + digitalWrite(sr->clockEnable, HIGH); + + return incoming; +} diff --git a/src/165.h b/src/165.h new file mode 100644 index 0000000..aed6aae --- /dev/null +++ b/src/165.h @@ -0,0 +1,17 @@ +#ifndef __165__ +#define __165__ + +#include "Arduino.h" +#include + +typedef struct SR165 { + uint8_t parallelLoadIn; + uint8_t clockEnable; + uint8_t complementaryOut; + uint8_t clockIn; +} SR165; + +SR165 NewSR165(uint8_t pl, uint8_t ce, uint8_t cp, uint8_t q7); +byte SR165_read(SR165 *sr); + +#endif diff --git a/src/595n.cpp b/src/595n.cpp new file mode 100644 index 0000000..2ccc7c0 --- /dev/null +++ b/src/595n.cpp @@ -0,0 +1,22 @@ +#include "Arduino.h" +#include "595n.h" + +SR595N NewSR595N(uint8_t ser, uint8_t rclk, uint8_t srclk) { + struct SR595N newSR = { + .ser = ser, + .rclk = rclk, + .srclk = srclk + }; + + pinMode(newSR.ser, OUTPUT); + pinMode(newSR.rclk, OUTPUT); + pinMode(newSR.srclk, OUTPUT); + + return newSR; +} + +void SR595N_write(SR595N *sr, uint8_t value) { + digitalWrite(sr->rclk, LOW); + shiftOut(sr->ser, sr->srclk, MSBFIRST, value); + digitalWrite(sr->rclk, HIGH); +} diff --git a/src/595n.h b/src/595n.h new file mode 100644 index 0000000..b02620b --- /dev/null +++ b/src/595n.h @@ -0,0 +1,15 @@ +#ifndef __595N__ +#define __595N__ + +#include + +typedef struct SR595N { + uint8_t ser; + uint8_t rclk; + uint8_t srclk; +} SR595N; + +SR595N NewSR595N(uint8_t ser, uint8_t rclkh, uint8_t srclk); +void SR595N_write(SR595N *sr, uint8_t value); + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..b619ec8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,48 @@ +/* BtnBOX by Eduardo Silva + * Notes: + * calling Wire.begin() will take use of the pins 2 and 3. Maybe try not using + * them from the getgo + */ + +#include +#include "595n.h" +#include "165.h" +// #include "Wire.h" + +// NOTES - 595N +// On the board, the first output pin on the SR595 is Qb +// Which means that our outputs go from 0b00000010 to 0b01111110 +#define IN_SERIAL_PIN 4 // SER - pin14 (Serial Pin) +#define IN_LATCH_PIN 5 // RCLK - pin12 (Latch Pin) +#define IN_CLOCK_PIN 6 // SRCLK - pin11 (Clock Pin) +/* ++-- --+ +|P5 P4 P3 P2 P1 P0| ++-----------------+ +P0 0b00000010 +P1 +*/ + +// NOTES - 165 +#define OUT_PARALLEL_LOAD_IN 10 // PL - pin1 (Async Parallel Load In) +#define OUT_CLOCK_IN 9 // CP - pin2 (Clock In) +#define OUT_COMPLEMENTARY_OUT 8 // Q7 - pin7 (Complementary Output) +#define OUT_CLOCK_ENABLE 7 // CE - pin15 (Clock Enable) + +SR595N input = NewSR595N(IN_SERIAL_PIN, IN_LATCH_PIN, IN_CLOCK_PIN); +SR165 output = NewSR165(OUT_PARALLEL_LOAD_IN, OUT_CLOCK_ENABLE, + OUT_CLOCK_IN, OUT_COMPLEMENTARY_OUT); + +void setup() { + Serial.begin(115200); + + SR595N_write(&input, 0b10101010); +} + +void loop(void) { + delay(200); + + byte srOutput = SR165_read(&output); + + Serial.println(srOutput, BIN); +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html