Taiga Develop 2 долоо хоног өмнө
parent
commit
67e239c9d1

+ 28 - 0
build-generic/make.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+
+CC=gcc
+CC_FLAGS="-O2 -Wall -Wextra -DCHLCD_STDIO_TESTING"
+
+AR=ar
+AR_FLAGS="rcs"
+
+BUILD=$(dirname $(realpath $0))
+SOURCE=$BUILD/../sources
+HEADERS=$BUILD/../headers
+OUTPUT=libchlcd.a
+
+rm -f $BUILD/*.o
+rm -f $BUILD/*.a
+
+for count in $SOURCE/*.c; do
+    file_name=$(basename $count .c)
+    file_full_name=$file_name.c
+    output_name=$file_name.o
+
+    echo "Building $file_full_name..."
+    $CC $CC_FLAGS $SOURCE/$file_full_name -c -o $BUILD/$output_name -I$HEADERS
+done
+
+echo ""
+echo "Making static library..."
+$AR $AR_FLAGS $BUILD/$OUTPUT $(ls $BUILD/*.o)

+ 15 - 0
headers/cx/chlcd.h

@@ -0,0 +1,15 @@
+#ifndef CX_CHLCD_H_INCLUDED
+#define CX_CHLCD_H_INCLUDED
+
+#include "cx/chlcd/types.h"
+#include "cx/chlcd/error.h"
+#include "cx/chlcd/command.h"
+#include "cx/chlcd/connector.h"
+#include "cx/chlcd/creator.h"
+#include "cx/chlcd/decoder.h"
+#include "cx/chlcd/display.h"
+#include "cx/chlcd/sender.h"
+#include "cx/chlcd/hal.h"
+#include "cx/chlcd/api.h"
+
+#endif

+ 10 - 0
headers/cx/chlcd/__helper.h

@@ -0,0 +1,10 @@
+#ifndef CX_CHLCD___HELPER_H_INCLUDED
+#define CX_CHLCD___HELPER_H_INCLUDED
+
+#define __R(X) do { \
+    if ((X) != CHLCD_SUCCESS) { \
+        return CHLCD_BAD_ARGUMENT; \
+    } \
+} while (0)
+
+#endif

+ 12 - 0
headers/cx/chlcd/api.h

@@ -0,0 +1,12 @@
+#ifndef CX_CHLCD_API_H_INCLUDED
+#define CX_CHLCD_API_H_INCLUDED
+
+#include "cx/chlcd/types.h"
+#include "cx/chlcd/error.h"
+#include "cx/chlcd/display.h"
+
+chlcd_error_t chlcd_display_init(chlcd_display_t *self);
+chlcd_error_t chlcd_display_clear(chlcd_display_t *self);
+chlcd_error_t chlcd_display_print(chlcd_display_t *self, char *content);
+
+#endif

+ 14 - 0
headers/cx/chlcd/command.h

@@ -0,0 +1,14 @@
+#ifndef CX_CHLCD_COMMAND_H_INCLUDED
+#define CX_CHLCD_COMMAND_H_INCLUDED
+
+typedef enum chlcd_command_e {
+    CHLCD_RESET,
+    CHLCD_INIT,
+    CHLCD_CLEAR,
+    CHLCD_SHOW_CURSOR,
+    CHLCD_HIDE_CURSOR,
+    CHLCD_MOVE_CURSOR,
+    CHLCD_SEND_CHAR
+} chlcd_command_t;
+
+#endif

+ 30 - 0
headers/cx/chlcd/connector.h

@@ -0,0 +1,30 @@
+#ifndef CX_CHLCD_CONNECTOR_H_INCLUDED
+#define CX_CHLCD_CONNECTOR_H_INCLUDED
+
+#include "cx/chlcd/types.h"
+
+typedef struct chlcd_hd44780_direct_connector_s {
+    chlcd_pin_t e;
+    chlcd_pin_t rs;
+    chlcd_pin_t d4;
+    chlcd_pin_t d5;
+    chlcd_pin_t d6;
+    chlcd_pin_t d7;
+} chlcd_hd44780_direct_connector_t;
+
+typedef struct chlcd_hd44780_shift_register_connector_s {
+    chlcd_pin_t register_latch;
+    chlcd_pin_t register_clock;
+    chlcd_pin_t register_data;
+   
+    chlcd_bitcount_t e;
+    chlcd_bitcount_t rs;
+    chlcd_bitcount_t d4;
+    chlcd_bitcount_t d5;
+    chlcd_bitcount_t d6;
+    chlcd_bitcount_t d7;
+
+    uint8_t last_state;
+} chlcd_hd44780_shift_register_connector_t;
+
+#endif

+ 23 - 0
headers/cx/chlcd/creator.h

@@ -0,0 +1,23 @@
+#ifndef CX_CHLCD_CREATOR_H_INCLUDED
+#define CX_CHLCD_CREATOR_H_INCLUDED
+
+#include "cx/chlcd/types.h"
+#include "cx/chlcd/error.h"
+#include "cx/chlcd/display.h"
+#include "cx/chlcd/connector.h"
+
+chlcd_error_t chlcd_hd44780_direct_create(
+    chlcd_display_t *self,
+    chlcd_hd44780_direct_connector_t *connector,
+    chlcd_size_t width,
+    chlcd_size_t height
+);
+
+chlcd_error_t chlcd_hd44780_shift_register_create(
+    chlcd_display_t *self,
+    chlcd_hd44780_shift_register_connector_t *connector,
+    chlcd_size_t width,
+    chlcd_size_t height
+);
+
+#endif

+ 18 - 0
headers/cx/chlcd/decoder.h

@@ -0,0 +1,18 @@
+#ifndef CX_CHLCD_DECODER_H_INCLUDED
+#define CX_CHLCD_DECODER_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cx/chlcd/error.h"
+#include "cx/chlcd/command.h"
+#include "cx/chlcd/types.h"
+
+chlcd_error_t chlcd_hd44780_decoder(
+    chlcd_command_t command,
+    chlcd_data_t content,
+    void *connector,
+    chlcd_sender_t sender
+);
+
+#endif

+ 19 - 0
headers/cx/chlcd/display.h

@@ -0,0 +1,19 @@
+#ifndef CX_CHLCD_DISPLAY_H_INCLUDED
+#define CX_CHLCD_DISPLAY_H_INCLUDED
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "cx/chlcd/types.h"
+#include "cx/chlcd/connector.h"
+
+typedef struct chlcd_display_s {
+    chlcd_sender_t sender;
+    chlcd_decoder_t decoder;
+    chlcd_size_t width;
+    chlcd_size_t height;
+    void *connector;
+} chlcd_display_t;
+
+#endif

+ 10 - 0
headers/cx/chlcd/error.h

@@ -0,0 +1,10 @@
+#ifndef CX_CHLCD_ERROR_H_INCLUDED
+#define CX_CHLCD_ERROR_H_INCLUDED
+
+typedef enum chlcd_error_e {
+    CHLCD_SUCCESS,
+    CHLCD_BAD_ARGUMENT,
+    CHLCD_SEND_ERROR
+} chlcd_error_t;
+
+#endif

+ 68 - 0
headers/cx/chlcd/hal.h

@@ -0,0 +1,68 @@
+#ifndef CX_CHLCD_HAL_H_INCLUDED
+#define CX_CHLCD_HAL_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cx/chlcd/types.h"
+
+#ifdef CHLCD_ON_ESP
+
+static inline chlcd_error_t chlcd_pin_set_output(chlcd_pin_t target) {
+
+}
+
+static inline chlcd_error_t chlcd_pin_write(chlcd_pin_t target, bool state) {
+
+}
+
+static inline chlcd_error_t chlcd_pin_set_pwm(chlcd_pin_t target) {
+
+}
+
+static inline chlcd_error_t chlcd_pin_write_pwm(
+    chlcd_pin_t target, 
+    uint16_t pwm
+) {
+
+}
+
+static inline chlcd_error_t chlcd_sleep_us(uint32_t time) {
+
+}
+
+#elifdef  CHLCD_STDIO_TESTING
+
+#include <stdio.h>
+
+static inline chlcd_error_t chlcd_pin_set_output(chlcd_pin_t target) {
+    printf("Pin %u mode set to output.\n", (uint32_t) target);
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t chlcd_pin_write(chlcd_pin_t target, bool state) {
+    printf("Pin %u set to %s.\n", (uint32_t) target, state ? "HIGH" : "LOW");
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t chlcd_pin_set_pwm(chlcd_pin_t target) {
+    printf("Pin %u mode set to PWM.\n", (uint32_t) target);
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t chlcd_pin_write_pwm(
+    chlcd_pin_t target,
+    uint16_t pwm
+) {
+    printf("Pin %u write to PWM %i.\n", (uint32_t) target, pwm);
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t chlcd_sleep_us(uint32_t time) {
+    printf("Wait for %u ns.\n", time);
+    return CHLCD_SUCCESS;
+}
+
+#endif
+
+#endif

+ 23 - 0
headers/cx/chlcd/sender.h

@@ -0,0 +1,23 @@
+#ifndef CX_CHLCD_SENDER_H_INCLUDED
+#define CX_CHLCD_SENDER_H_INCLUDED
+
+#include <stdbool.h>
+
+#include "cx/chlcd/types.h"
+#include "cx/chlcd/error.h"
+
+chlcd_error_t chlcd_hd44780_direct_sender(
+    void *self,
+    chlcd_data_t content,
+    bool is_command,
+    bool is_half_word
+);
+
+chlcd_error_t chlcd_hd44780_shift_register_sender(
+    void *self,
+    chlcd_data_t content,
+    bool is_command,
+    bool is_half_word
+);
+
+#endif

+ 41 - 0
headers/cx/chlcd/types.h

@@ -0,0 +1,41 @@
+#ifndef CX_CHLCD_TYPES_H_INCLUDED
+#define CX_CHLCD_TYPES_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef CHLCD_ON_ESP
+#define chlcd_pin_t gpio_num_t
+#endif
+
+#ifdef CHLCD_STDIO_TESTING
+#define chlcd_pin_t uint32_t
+#endif
+
+#ifndef chlcd_pin_t 
+#define chlcd_pin_t uint32_t
+#endif
+
+typedef uint8_t chlcd_size_t;
+typedef uint8_t chlcd_bitcount_t;
+struct chlcd_display_s;
+struct chlcd_connector_s;
+enum chlcd_command_e;
+enum chlcd_error_e;
+typedef uint8_t chlcd_data_t;
+
+typedef enum chlcd_error_e (*chlcd_sender_t)(
+    void *self, 
+    chlcd_data_t content,
+    bool is_command,
+    bool is_half_word
+);
+
+typedef enum chlcd_error_e (*chlcd_decoder_t)(
+    enum chlcd_command_e command,
+    chlcd_data_t content,
+    void *connector,
+    chlcd_sender_t sender
+);
+
+#endif

+ 28 - 0
sources/creator_hd44780_direct.c

@@ -0,0 +1,28 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <cx/chlcd.h>
+
+chlcd_error_t chlcd_hd44780_direct_create(
+    chlcd_display_t *self,
+    chlcd_hd44780_direct_connector_t *connector,
+    chlcd_size_t width,
+    chlcd_size_t height
+) {
+    if (connector == NULL) {
+        return CHLCD_BAD_ARGUMENT;
+    }
+
+    if (width == 0 || height == 0) {
+        return CHLCD_BAD_ARGUMENT;
+    }
+
+    self->width = width;
+    self->height = height;
+    self->sender = chlcd_hd44780_direct_sender;
+    self->decoder = chlcd_hd44780_decoder;
+    self->connector = (void *) connector;
+
+    return CHLCD_SUCCESS;
+}

+ 20 - 0
sources/display.c

@@ -0,0 +1,20 @@
+#include <cx/chlcd.h>
+
+chlcd_error_t chlcd_display_init(chlcd_display_t *self) {
+    chlcd_error_t result;
+
+    result = self->decoder(CHLCD_INIT, 0x00, self->connector, self->sender);
+ 
+    if (result != CHLCD_SUCCESS) {
+        return result;
+    }
+
+    result = self->decoder(CHLCD_CLEAR, 0x00, self->connector, self->sender);
+
+    if (result != CHLCD_SUCCESS) {
+        return result;
+    }
+
+    return CHLCD_SUCCESS;
+}
+

+ 71 - 0
sources/hd44780_decoder.c

@@ -0,0 +1,71 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <cx/chlcd.h>
+#include <cx/chlcd/__helper.h>
+
+
+static inline chlcd_error_t __chlcd_hd44780_decoder_init(
+    void *connector,
+    chlcd_sender_t sender
+) {
+    if (sender(connector, 0b0010, true, true) != CHLCD_SUCCESS) {
+        return CHLCD_SEND_ERROR;
+    }
+
+    if (sender(connector, 0b00001111, true, false) != CHLCD_SUCCESS) {
+        return CHLCD_SEND_ERROR;
+    }
+
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t __chlcd_hd44780_decoder_clear(
+    void *connector,
+    chlcd_sender_t sender
+) {
+    if (sender(connector, 0b00000001, true, false) != CHLCD_SUCCESS) {
+        return CHLCD_SEND_ERROR;
+    }
+    
+    if (sender(connector, 0b00000010, true, false) != CHLCD_SUCCESS) {
+        return CHLCD_SEND_ERROR;
+    }
+
+    return CHLCD_SUCCESS;
+}
+
+static inline chlcd_error_t __chlcd_hd44780_decoder_send_char(
+    void *connector,
+    chlcd_sender_t sender,
+    chlcd_data_t content
+) {
+    return sender(connector, content, false, false);
+}
+
+chlcd_error_t chlcd_hd44780_decoder(
+    chlcd_command_t command,
+    chlcd_data_t content,
+    void *connector,
+    chlcd_sender_t sender
+) {
+    switch (command) {
+        case CHLCD_INIT:
+            return __chlcd_hd44780_decoder_init(connector, sender);
+
+        case CHLCD_CLEAR:
+            return __chlcd_hd44780_decoder_clear(connector, sender);
+
+        case CHLCD_SEND_CHAR:
+            return __chlcd_hd44780_decoder_send_char(
+                connector, 
+                sender, 
+                content
+            ); 
+
+        default:
+            return CHLCD_BAD_ARGUMENT;
+    }
+}   
+

+ 76 - 0
sources/hd44780_direct_sender.c

@@ -0,0 +1,76 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <cx/chlcd.h>
+#include <cx/chlcd/__helper.h>
+
+
+chlcd_error_t chlcd_hd44780_direct_sender_init(void *self_pointer) {
+    chlcd_hd44780_direct_connector_t *self 
+    = (chlcd_hd44780_direct_connector_t *) self_pointer;
+
+    __R(chlcd_pin_set_output(self->e));
+    __R(chlcd_pin_set_output(self->rs));
+    __R(chlcd_pin_set_output(self->d4));
+    __R(chlcd_pin_set_output(self->d5));
+    __R(chlcd_pin_set_output(self->d6));
+    __R(chlcd_pin_set_output(self->d7));
+
+    __R(chlcd_pin_write(self->d7, false));
+    __R(chlcd_pin_write(self->d6, false));
+    __R(chlcd_pin_write(self->d5, false));
+    __R(chlcd_pin_write(self->d4, false));
+    __R(chlcd_pin_write(self->rs, false));
+    __R(chlcd_pin_write(self->e, false));
+    
+    return CHLCD_SUCCESS;
+}
+
+chlcd_error_t __chlcd_hd44780_direct_sender_send_half_byte(
+    chlcd_hd44780_direct_connector_t *self,
+    uint8_t content,
+    bool is_command
+) {
+    __R(chlcd_pin_write(self->d7, (content & 0b10000000)));
+    __R(chlcd_pin_write(self->d6, (content & 0b01000000)));
+    __R(chlcd_pin_write(self->d5, (content & 0b00100000)));
+    __R(chlcd_pin_write(self->d4, (content & 0b00010000)));
+    __R(chlcd_pin_write(self->rs, !is_command));
+
+    __R(chlcd_pin_write(self->e, true));
+    __R(chlcd_sleep_us(2000));
+    __R(chlcd_pin_write(self->e, false));
+    __R(chlcd_sleep_us(2000));
+
+    return CHLCD_SUCCESS;
+}
+
+chlcd_error_t chlcd_hd44780_direct_sender(
+    void *self_pointer,
+    chlcd_data_t content,
+    bool is_command,
+    bool is_half_word
+) {
+    chlcd_hd44780_direct_connector_t *self 
+    = (chlcd_hd44780_direct_connector_t *) self_pointer;
+
+    if (!is_half_word) {
+        __R(__chlcd_hd44780_direct_sender_send_half_byte(
+            self, 
+            content,
+            is_command
+        ));
+    }
+
+    content = content << 4;
+
+    __R(__chlcd_hd44780_direct_sender_send_half_byte(
+        self, 
+        content,
+        is_command
+    ));
+
+    return CHLCD_SUCCESS;
+}
+

+ 109 - 0
sources/hd44780_shift_register.c

@@ -0,0 +1,109 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <cx/chlcd.h>
+#include <cx/chlcd/__helper.h>
+
+
+static chlcd_error_t __chlcd_hd44780_shift_register_set_byte(
+    chlcd_hd44780_shift_register_connector_t *self,
+    uint8_t content
+) {
+    for (uint8_t count = 0; count < 8; ++count) {
+        bool current = (content & 0b10000000) != 0x00;
+        content = content << 1;
+
+        __R(chlcd_pin_write(self->register_data, current));
+        __R(chlcd_pin_write(self->register_clock, true));
+        __R(chlcd_sleep_us(20));
+        __R(chlcd_pin_write(self->register_clock, false));
+        __R(chlcd_sleep_us(20));
+    }
+
+    __R(chlcd_pin_write(self->register_latch, true));
+    __R(chlcd_sleep_us(20));
+    __R(chlcd_pin_write(self->register_latch, false));
+
+    self->last_state = content; 
+    return CHLCD_SUCCESS;
+}
+
+chlcd_error_t chlcd_hd44780_shift_register_init(void *self_pointer) {
+    chlcd_hd44780_shift_register_connector_t *self 
+    = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
+
+    __R(chlcd_pin_set_output(self->register_latch));
+    __R(chlcd_pin_set_output(self->register_clock));
+    __R(chlcd_pin_set_output(self->register_data));
+    
+    __R(chlcd_pin_write(self->register_data, false));
+    __R(chlcd_pin_write(self->register_clock, false));
+    __R(chlcd_pin_write(self->register_latch, false));
+
+    __R(chlcd_sleep_us(20));
+
+    __R(__chlcd_hd44780_shift_register_set_byte(self, 0x00));
+
+    return CHLCD_SUCCESS;
+}
+
+chlcd_error_t __chlcd_hd44780_shift_register_send_half_byte(
+    chlcd_hd44780_shift_register_connector_t *self,
+    uint8_t content,
+    bool is_command
+) {
+    uint8_t d7 = (content & 0b10000000) ? 0b1 : 0b0;
+    uint8_t d6 = (content & 0b01000000) ? 0b1 : 0b0;
+    uint8_t d5 = (content & 0b00100000) ? 0b1 : 0b0;
+    uint8_t d4 = (content & 0b00010000) ? 0b1 : 0b0;
+    uint8_t rs = is_command ? 0b0 : 0b1;
+    uint8_t e_mask = 0b1 << self->e;
+
+    uint8_t target = 0x00;
+    target |= (d7 << self->d7);
+    target |= (d6 << self->d6);
+    target |= (d5 << self->d5);
+    target |= (d4 << self->d4);
+    target |= (rs << self->rs);
+    target |= e_mask;
+
+    __R(__chlcd_hd44780_shift_register_set_byte(self, target));
+    __R(chlcd_sleep_us(2000));
+
+    target &= ~e_mask;
+
+    __R(__chlcd_hd44780_shift_register_set_byte(self, target));
+    __R(chlcd_sleep_us(2000));
+
+    return CHLCD_SUCCESS;
+}
+
+chlcd_error_t chlcd_hd44780_shift_register_sender(
+    void *self_pointer,
+    chlcd_data_t content,
+    bool is_command,
+    bool is_half_word
+) {
+    chlcd_hd44780_shift_register_connector_t *self
+    = (chlcd_hd44780_shift_register_connector_t *) self_pointer;
+
+    if (!is_half_word) {
+        __R(__chlcd_hd44780_shift_register_send_half_byte(
+            self, 
+            content, 
+            is_command
+        ));
+    }
+
+    content = content << 4;
+
+    __R(__chlcd_hd44780_shift_register_send_half_byte(
+        self, 
+        content, 
+        is_command
+    ));
+    
+    return CHLCD_SUCCESS;
+}
+

+ 24 - 0
tests/000-default/make.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+CC=gcc
+CC_FLAGS="-O2"
+
+OWN=$(dirname $(realpath $0))
+TEST_SOURCE=$OWN/testing.c
+TEST_OUTPUT=$OWN/testing.app
+HEADERS=$OWN/../../headers
+LIBRARY=$OWN/../../build-generic
+LIBRARY_MAKE=$OWN/../../build-generic/make.sh
+
+rm -f $TEST_OUTPUT
+
+echo "Rebuilding..."
+$LIBRARY_MAKE
+
+echo ""
+echo "Build test..."
+$CC $CC_FLAGS $TEST_SOURCE -o $TEST_OUTPUT -I$HEADERS -L$LIBRARY -lchlcd 
+
+echo "Running..."
+echo ""
+$TEST_OUTPUT

+ 10 - 0
tests/000-default/testing.c

@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <cx/chlcd.h>
+
+int main(int argc, char *argv[]) {
+    puts("Start CX-CHLCD in testing mode.");
+
+
+
+    return 0;
+}

+ 24 - 0
tests/001-lcd-init/make.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+CC=gcc
+CC_FLAGS="-O2"
+
+OWN=$(dirname $(realpath $0))
+TEST_SOURCE=$OWN/testing.c
+TEST_OUTPUT=$OWN/testing.app
+HEADERS=$OWN/../../headers
+LIBRARY=$OWN/../../build-generic
+LIBRARY_MAKE=$OWN/../../build-generic/make.sh
+
+rm -f $TEST_OUTPUT
+
+echo "Rebuilding..."
+$LIBRARY_MAKE
+
+echo ""
+echo "Build test..."
+$CC $CC_FLAGS $TEST_SOURCE -o $TEST_OUTPUT -I$HEADERS -L$LIBRARY -lchlcd 
+
+echo "Running..."
+echo ""
+$TEST_OUTPUT

+ 27 - 0
tests/001-lcd-init/testing.c

@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <cx/chlcd.h>
+
+int main(int argc, char *argv[]) {
+    puts("Start CX-CHLCD in testing mode.");
+
+    chlcd_hd44780_direct_connector_t connector[1] = {0};
+    connector->d7 = 7;
+    connector->d6 = 6;
+    connector->d5 = 5;
+    connector->d4 = 4;
+    connector->rs = 3;
+    connector->e = 2;
+
+    chlcd_display_t display[1] = {0};
+
+    chlcd_hd44780_direct_create(
+        display,
+        connector,
+        16,
+        2
+    );
+    
+    chlcd_display_init(display);
+
+    return 0;
+}