M simavr/main.c => simavr/main.c +18 -42
@@ 6,62 6,38 @@
int main(void)
{
- DDRB = 0xFF;
- PORTB = 0xFF;
-
- _delay_ms(100);
- DDRB = 0;
- PORTB = 0;
// SIPO
- ShiftRegisterHandle sipoSrHandle = avr_sipo_shift_register_create(
- data_position_create(&DDRB, &PORTB, &PINB, 0), // SIPO_SRCLR
- data_position_create(&DDRB, &PORTB, &PINB, 1), // SIPO_SRCLK
- data_position_create(&DDRB, &PORTB, &PINB, 2), // SIPO_SER
- data_position_create(&DDRB, &PORTB, &PINB, 3), // SIPO_OE
- data_position_create(&DDRB, &PORTB, &PINB, 4), // SIPO_RCLK
+ const SipoShiftRegister sipoSr = avr_sipo_shift_register_create(
+ data_position_create(&PINB, 0), // SIPO_SRCLR
+ data_position_create(&PINB, 1), // SIPO_SRCLK
+ data_position_create(&PINB, 2), // SIPO_SER
+ data_position_create(&PINB, 3), // SIPO_OE
+ data_position_create(&PINB, 4), // SIPO_RCLK
1
);
- _delay_ms(100);
- avr_sipo_shift_register_init(sipoSrHandle);
- _delay_ms(100);
-
- avr_sipo_shift_register_write_byte(sipoSrHandle, 207); // 0b11001111
- _delay_ms(100);
- avr_sipo_shift_register_push_data_to_output(sipoSrHandle);
- _delay_ms(100);
- avr_sipo_shift_register_enable_output(sipoSrHandle);
- _delay_ms(100);
+ avr_sipo_shift_register_init(sipoSr);
- avr_sipo_shift_register_destroy(sipoSrHandle);
- _delay_ms(100);
+ avr_sipo_shift_register_write_byte(sipoSr, 207); // 0b11001111
+ avr_sipo_shift_register_push_data_to_output(sipoSr);
+ avr_sipo_shift_register_enable_output(sipoSr);
// ------------
// PISO
_delay_ms(100);
- ShiftRegisterHandle pisoSrHandle = avr_piso_shift_register_create(
- data_position_create(&DDRC, &PORTC, &PINC, 0), // PISO_CE
- data_position_create(&DDRC, &PORTC, &PINC, 1), // PISO_CP
- data_position_create(&DDRC, &PORTC, &PINC, 2), // PISO_Q7
- data_position_create(&DDRC, &PORTC, &PINC, 3), // PISO_PL
+ const PisoShiftRegister pisoSr = avr_piso_shift_register_create(
+ data_position_create(&PINC, 0), // PISO_CE
+ data_position_create(&PINC, 1), // PISO_CP
+ data_position_create(&PINC, 2), // PISO_Q7
+ data_position_create(&PINC, 3), // PISO_PL
1
);
- _delay_ms(100);
-
- avr_piso_shift_register_init(pisoSrHandle);
- avr_piso_shift_register_parallel_load(pisoSrHandle);
- avr_piso_shift_register_read_byte(pisoSrHandle);
+ avr_piso_shift_register_init(pisoSr);
- avr_piso_shift_register_destroy(sipoSrHandle);
-
- DDRB = 0xFF;
- PORTB = 0xFF;
-
- _delay_ms(100);
- DDRB = 0;
- PORTB = 0;
+ avr_piso_shift_register_parallel_load(pisoSr);
+ avr_piso_shift_register_read_byte(pisoSr);
return 0;
}
M src/sr/data_position.c => src/sr/data_position.c +12 -22
@@ 1,42 1,32 @@
#include "shift_register_internal.h"
#include <stdlib.h>
-DataPosition* data_position_create(volatile byte* ddr, volatile byte* port, volatile byte* pin, byte position) {
- DataPosition* dp = (DataPosition*) malloc(sizeof(DataPosition));
- dp->ddr = ddr;
- dp->port = port;
- dp->pin = pin;
- dp->position = position;
-
+const DataPosition data_position_create(volatile byte* pin, byte position) {
+ DataPosition dp = { pin, position };
return dp;
}
-void data_position_destroy(const DataPosition* position)
-{
- free((DataPosition*) position);
-}
-
-bool data_position_get_pin(const DataPosition* position)
+bool data_position_get_pin(const DataPosition position)
{
- return get_value(position->pin, position->position);
+ return get_value(position.pin, position.position);
}
-void data_position_set_port(const DataPosition* position)
+void data_position_set_port(const DataPosition position)
{
- set_value(position->port, position->position);
+ set_value(position.pin + SR_PORT_OFFSET, position.position);
}
-void data_position_reset_port(const DataPosition* position)
+void data_position_reset_port(const DataPosition position)
{
- reset_value(position->port, position->position);
+ reset_value(position.pin + SR_PORT_OFFSET, position.position);
}
-void data_position_set_ddr(const DataPosition* position)
+void data_position_set_ddr(const DataPosition position)
{
- set_value(position->ddr, position->position);
+ set_value(position.pin + SR_DDR_OFFSET, position.position);
}
-void data_position_reset_ddr(const DataPosition* position)
+void data_position_reset_ddr(const DataPosition position)
{
- reset_value(position->ddr, position->position);
+ reset_value(position.pin + SR_DDR_OFFSET, position.position);
}=
\ No newline at end of file
M src/sr/piso_shift_register.c => src/sr/piso_shift_register.c +27 -43
@@ 2,72 2,56 @@
#include <util/delay.h>
#include <stdlib.h>
-ShiftRegisterHandle avr_piso_shift_register_create(
- const DataPosition* clockEnable,
- const DataPosition* clockPulse,
- const DataPosition* output,
- const DataPosition* parallelLoad,
+const PisoShiftRegister avr_piso_shift_register_create(
+ const DataPosition clockEnable,
+ const DataPosition clockPulse,
+ const DataPosition output,
+ const DataPosition parallelLoad,
int waitTime
)
{
- PisoShiftRegister* shiftRegister = (PisoShiftRegister*) calloc(1, sizeof(PisoShiftRegister));
-
- shiftRegister->output = output;
- shiftRegister->parallelLoad = parallelLoad;
- shiftRegister->shiftRegister.clockEnable = clockEnable;
- shiftRegister->shiftRegister.clockPulse = clockPulse;
- shiftRegister->shiftRegister.waitTime = waitTime;
-
- return shiftRegister;
+ const ShiftRegister shiftRegister = avr_shift_register_create(SR_PISO, clockEnable, clockPulse, waitTime);
+ PisoShiftRegister pisoShiftRegister = { shiftRegister, output, parallelLoad };
+ return pisoShiftRegister;
}
-void avr_piso_shift_register_init(ShiftRegisterHandle shiftRegisterHandle)
-{
- PisoShiftRegister* shiftRegister = (PisoShiftRegister*) shiftRegisterHandle;
-
- data_position_reset_ddr(shiftRegister->output);
- data_position_set_ddr(shiftRegister->parallelLoad);
- data_position_set_ddr(shiftRegister->shiftRegister.clockPulse);
- data_position_set_ddr(shiftRegister->shiftRegister.clockEnable);
-
- data_position_set_port(shiftRegister->parallelLoad);
+void avr_piso_shift_register_init(const PisoShiftRegister shiftRegister)
+{
+ data_position_reset_ddr(shiftRegister.output);
+ data_position_set_ddr(shiftRegister.parallelLoad);
+ data_position_set_ddr(shiftRegister.shiftRegister.clockPulse);
+ data_position_set_ddr(shiftRegister.shiftRegister.clockEnable);
- avr_shift_register_enable_clock(shiftRegisterHandle);
-}
+ data_position_set_port(shiftRegister.parallelLoad);
-void avr_piso_shift_register_destroy(ShiftRegisterHandle shiftRegisterHandle)
-{
- free((PisoShiftRegister*) shiftRegisterHandle);
+ avr_shift_register_enable_clock(shiftRegister.shiftRegister);
}
-void avr_piso_shift_register_parallel_load(ShiftRegisterHandle shiftRegisterHandle)
+void avr_piso_shift_register_parallel_load(const PisoShiftRegister shiftRegister)
{
- PisoShiftRegister* shiftRegister = (PisoShiftRegister*) shiftRegisterHandle;
-
- data_position_reset_port(shiftRegister->parallelLoad);
- _delay_ms(1);
- data_position_set_port(shiftRegister->parallelLoad);
+ data_position_reset_port(shiftRegister.parallelLoad);
+ sleep(shiftRegister.shiftRegister.waitTime);
+ data_position_set_port(shiftRegister.parallelLoad);
}
-void avr_piso_shift_register_shift(ShiftRegisterHandle shiftRegisterHandle)
+void avr_piso_shift_register_shift(const PisoShiftRegister shiftRegister)
{
- avr_shift_register_clock_pulse(shiftRegisterHandle);
+ avr_shift_register_clock_pulse(shiftRegister.shiftRegister);
}
-bool avr_piso_shift_register_read_bit(ShiftRegisterHandle shiftRegisterHandle)
+bool avr_piso_shift_register_read_bit(const PisoShiftRegister shiftRegister)
{
- PisoShiftRegister* shiftRegister = (PisoShiftRegister*) shiftRegisterHandle;
-
- return data_position_get_pin(shiftRegister->output);
+ return data_position_get_pin(shiftRegister.output);
}
-byte avr_piso_shift_register_read_byte(ShiftRegisterHandle shiftRegisterHandle)
+byte avr_piso_shift_register_read_byte(const PisoShiftRegister shiftRegister)
{
byte output = 0;
for (int i = 0; i < 8; i++)
{
- output |= avr_piso_shift_register_read_bit(shiftRegisterHandle) << i;
+ output |= avr_piso_shift_register_read_bit(shiftRegister) << i;
+ avr_piso_shift_register_shift(shiftRegister);
}
return output;
M src/sr/seduce.h => src/sr/seduce.h +114 -103
@@ 1,77 1,80 @@
#ifndef _SHIFT_REGISTERS_SEDUCE
#define _SHIFT_REGISTERS_SEDUCE
-// TODO: make this working with flash memory so the data is not placed on RAM
-// TODO: assume PINB is x. then DDRB is x + 1 and PORTB is x + 2.
+#ifndef SR_DDR_OFFSET
+ #define SR_DDR_OFFSET 1
+#endif
-/**
- * @file seduce.h
- * @author Rutherther
- * @date 9 Sep 2020
- * @brief File containing public exports of the library.
- *
- * This header should be included in projects that use this library.
- * There aren't any other headers that should be imported.
- * Other headers suffixed using _internal should be used only
- * internally from within the library.
- *
- * @see DataPosition
- * @see ShiftRegisterHandle
- */
+#ifndef SR_PORT_OFFSET
+ #define SR_PORT_OFFSET 2
+#endif
-/**
- * @brief Handle to work with the shift registers.
- *
- * This handle can be obtained using @see avr_piso_shift_register_init for PISO
- * or @see avr_sipo_shift_register_init for SIPO.
- * PISO stands for parallel-in/serial-out (used for getting input from shift register).
- * SIPO stands for serial-in/parallel-out (used for passing output using shift register).
- *
- */
-typedef void* ShiftRegisterHandle;
typedef unsigned char bool;
typedef unsigned char byte;
/**
* @brief Hold data port info.
*
- * Structure used to hold DDR, PORT and PIN registers
+ * Structure used to hold PIN registers
* along with a bit position.
*
+ * DDR and PORT registers will be automatically located
+ * to save some RAM. offset of DDR can be set
+ * using #define SR_DDR_OFFSET (default 1). For PORT use
+ * #define SR_PORT_OFFSET (default 2). This number is then
+ * added to the PIN address
+ *
* Can be used to dynamically save a position of I/O .
*
* @note Function @see data_position_create can be used as an shorthand for creating DataPosition.
*
* Example usage:
* @code
- * data_position_create(&DDRA, &PORTA, &PINA, 1); // Pass position 1 of PINA
+ * data_position_create(&PINA, 1); // Pass position 1 of PINA
* @endcode
*/
typedef struct DataPosition {
- volatile byte* ddr;
- volatile byte* port;
volatile byte* pin;
byte position;
} DataPosition;
+typedef enum {
+ SR_PISO,
+ SR_SIPO
+} ShiftRegisterTypeHeader;
+
+typedef struct {
+ const ShiftRegisterTypeHeader type;
+ const DataPosition clockEnable;
+ const DataPosition clockPulse;
+ int waitTime;
+} ShiftRegister;
+
+typedef struct {
+ const ShiftRegister shiftRegister;
+ const DataPosition output;
+ const DataPosition parallelLoad;
+} PisoShiftRegister;
+
+typedef struct {
+ const ShiftRegister shiftRegister;
+ const DataPosition input;
+ const DataPosition outputEnable;
+ const DataPosition pushOutput;
+} SipoShiftRegister;
+
/**
* @brief Create DataPosition struct.
*
- * @param ddr Pointer to DDR register (for example &DDRA).
- * @param port Pointer to PORT register (for example &PORTA).
+ * Pointers to PORT and DDR are automatically calculated.
+ * Check out DataPosition documentation for more information.
+ *
* @param pin Pointer to PIN register (for example &PINA).
* @param position Position within the register.
* @return DataPosition
* @note 0 is for LSB. 7 is for MSB. PORTA1 can be used.
*/
-extern DataPosition* data_position_create(volatile byte* ddr, volatile byte* port, volatile byte* pin, byte position);
-
-/**
- * @brief Destroy DataPosition
- *
- * @param position
- */
-extern void data_position_destroy(const DataPosition* position);
+extern const DataPosition data_position_create(volatile byte* pin, byte position);
/**
* @brief Get PIN value of DataPosition.
@@ 80,7 83,7 @@ extern void data_position_destroy(const DataPosition* position);
* @return true When PIN (input) is HIGH.
* @return false When PIN (input) is LOW.
*/
-extern bool data_position_get_pin(const DataPosition* position);
+extern bool data_position_get_pin(const DataPosition position);
/**
* @brief Set PORT value of DataPosition.
@@ 91,7 94,7 @@ extern bool data_position_get_pin(const DataPosition* position);
*
* @param position
*/
-extern void data_position_set_port(const DataPosition* position);
+extern void data_position_set_port(const DataPosition position);
/**
* @brief Reset PORT value of DataPosition.
@@ 102,7 105,7 @@ extern void data_position_set_port(const DataPosition* position);
*
* @param position
*/
-extern void data_position_reset_port(const DataPosition* position);
+extern void data_position_reset_port(const DataPosition position);
/**
* @brief Set DDR value of DataPosition
@@ 111,7 114,7 @@ extern void data_position_reset_port(const DataPosition* position);
*
* @param position
*/
-extern void data_position_set_ddr(const DataPosition* position);
+extern void data_position_set_ddr(const DataPosition position);
/**
* @brief Reset DDR value of DataPosition.
@@ 120,7 123,7 @@ extern void data_position_set_ddr(const DataPosition* position);
*
* @param position
*/
-extern void data_position_reset_ddr(const DataPosition* position);
+extern void data_position_reset_ddr(const DataPosition position);
/*******************************************************************************
* *
@@ 130,14 133,36 @@ extern void data_position_reset_ddr(const DataPosition* position);
*******************************************************************************/
/**
+ * @brief Create shift register.
+ *
+ * This function creates generic shift register.
+ * Functions beginning with avr_piso_shift_register may be used
+ * with this type of ShiftRegister.
+ *
+ * @param type
+ * @param clockEnable
+ * @param clockPulse
+ * @param waitTime
+ * @return ShiftRegister
+ *
+ * @note You should always init the shift register after creating it. Use @see avr_piso_shift_register_init.
+ */
+extern const ShiftRegister avr_shift_register_create(
+ ShiftRegisterTypeHeader type,
+ const DataPosition clockEnable,
+ const DataPosition clockPulse,
+ int waitTime
+);
+
+/**
* @brief Send clock pulse to shift register.
*
* This function makes the clockPulse position HIGH for specified waitTime
* Then makes it LOW again.`
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_shift_register_clock_pulse(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_shift_register_clock_pulse(const ShiftRegister shiftRegister);
/**
* @brief Enable shift register clock.
@@ 149,10 174,10 @@ extern void avr_shift_register_clock_pulse(ShiftRegisterHandle shiftRegisterHand
* For SIPO registers if clockEnable is made low
* the register is also cleared.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
* @note This function will be called in the init function.
*/
-extern void avr_shift_register_enable_clock(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_shift_register_enable_clock(const ShiftRegister shiftRegister);
/**
* @brief Disable shift register clock.
@@ 162,9 187,9 @@ extern void avr_shift_register_enable_clock(ShiftRegisterHandle shiftRegisterHan
*
* @note some SIPO registers can be cleared using this function.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_shift_register_disable_clock(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_shift_register_disable_clock(const ShiftRegister shiftRegister);
/*******************************************************************************
* *
@@ 186,15 211,15 @@ extern void avr_shift_register_disable_clock(ShiftRegisterHandle shiftRegisterHa
* @param output Can be specified as Q7 in datasheet. Be careful not to use negative Q7.
* @param parallelLoad Can be specified as PL.
* @param waitTime Used to wait when pulsing the clock
- * @return ShiftRegisterHandle
+ * @return PisoShiftRegister
*
* @note You should always init the shift register after creating it. Use @see avr_piso_shift_register_init.
*/
-extern ShiftRegisterHandle avr_piso_shift_register_create(
- const DataPosition* clockEnable,
- const DataPosition* clockPulse,
- const DataPosition* output,
- const DataPosition* parallelLoad,
+extern const PisoShiftRegister avr_piso_shift_register_create(
+ const DataPosition clockEnable,
+ const DataPosition clockPulse,
+ const DataPosition output,
+ const DataPosition parallelLoad,
int waitTime
);
@@ 206,16 231,9 @@ extern ShiftRegisterHandle avr_piso_shift_register_create(
*
* @see avr_shift_register_enable_clock is also called to enable the clock.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_piso_shift_register_init(ShiftRegisterHandle shiftRegisterHandle);
-
-/**
- * @brief Destroy and free PISO shift register memory
- *
- * @param shiftRegisterHandle
- */
-extern void avr_piso_shift_register_destroy(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_piso_shift_register_init(const PisoShiftRegister shiftRegister);
/**
* @brief Asynchronously load the data
@@ 225,9 243,9 @@ extern void avr_piso_shift_register_destroy(ShiftRegisterHandle shiftRegisterHan
* PL port will be set LOW and then back
* HIGH after waitTime has passed.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_piso_shift_register_parallel_load(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_piso_shift_register_parallel_load(const PisoShiftRegister shiftRegister);
/**
* @brief Shift next bit
@@ 235,9 253,9 @@ extern void avr_piso_shift_register_parallel_load(ShiftRegisterHandle shiftRegis
* This function shifts next bit from the PISO shift register.
* It just makes the clockPulse HIGH and then LOW.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_piso_shift_register_shift(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_piso_shift_register_shift(const PisoShiftRegister shiftRegister);
/**
* @brief Read current bit
@@ 247,11 265,11 @@ extern void avr_piso_shift_register_shift(ShiftRegisterHandle shiftRegisterHandl
*
* @note You can read the whole byte using @see avr_piso_shift_register_read_byte
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
* @return true
* @return false
*/
-extern bool avr_piso_shift_register_read_bit(ShiftRegisterHandle shiftRegisterHandle);
+extern bool avr_piso_shift_register_read_bit(const PisoShiftRegister shiftRegister);
/**
* @brief Read byte from the shift register
@@ 261,10 279,10 @@ extern bool avr_piso_shift_register_read_bit(ShiftRegisterHandle shiftRegisterHa
*
* @note You can read one bit using @see avr_piso_shift_register_read_bit
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
* @return byte
*/
-extern byte avr_piso_shift_register_read_byte(ShiftRegisterHandle shiftRegisterHandle);
+extern byte avr_piso_shift_register_read_byte(const PisoShiftRegister shiftRegister);
/*******************************************************************************
* *
@@ 291,12 309,12 @@ extern byte avr_piso_shift_register_read_byte(ShiftRegisterHandle shiftRegisterH
*
* @note You should always init the shift register after creating it. Use @see avr_sipo_shift_register_init.
*/
-extern ShiftRegisterHandle avr_sipo_shift_register_create(
- const DataPosition* clockEnable, // SRCLR
- const DataPosition* clockPulse, // SRCLK
- const DataPosition* input, // SER
- const DataPosition* outputEnable, // OE
- const DataPosition* pushOutput, // RCLK
+extern const SipoShiftRegister avr_sipo_shift_register_create(
+ const DataPosition clockEnable, // SRCLR
+ const DataPosition clockPulse, // SRCLK
+ const DataPosition input, // SER
+ const DataPosition outputEnable, // OE
+ const DataPosition pushOutput, // RCLK
int waitTime
);
@@ 308,16 326,9 @@ extern ShiftRegisterHandle avr_sipo_shift_register_create(
*
* @see avr_shift_register_enable_clock is also called to enable the clock.
*
- * @param shiftRegisterHandle
- */
-extern void avr_sipo_shift_register_init(ShiftRegisterHandle shiftRegisterHandle);
-
-/**
- * @brief Destroy and free SIPO shift register memory
- *
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_destroy(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_init(const SipoShiftRegister shiftRegister);
/**
* @brief Shifts data by one position.
@@ 325,9 336,9 @@ extern void avr_sipo_shift_register_destroy(ShiftRegisterHandle shiftRegisterHan
* This function shifts next bit from the PISO shift register.
* It just makes the clockPulse HIGH and then LOW.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_shift(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_shift(const SipoShiftRegister shiftRegister);
/**
* @brief Write one bit to the shift register.
@@ 337,11 348,11 @@ extern void avr_sipo_shift_register_shift(ShiftRegisterHandle shiftRegisterHandl
*
* @note You can read the whole byte using @see avr_sipo_shift_register_write_byte
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
* @param data
* @param position
*/
-extern void avr_sipo_shift_register_write_bit(ShiftRegisterHandle shiftRegisterHandle, byte data, int position);
+extern void avr_sipo_shift_register_write_bit(const SipoShiftRegister shiftRegister, byte data, int position);
/**
* @brief Write whole byte to the shift register.
@@ 351,10 362,10 @@ extern void avr_sipo_shift_register_write_bit(ShiftRegisterHandle shiftRegisterH
*
* @note You can write only one bit using @see avr_sipo_shift_register_write_bit
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
* @param data
*/
-extern void avr_sipo_shift_register_write_byte(ShiftRegisterHandle shiftRegisterHandle, byte data);
+extern void avr_sipo_shift_register_write_byte(const SipoShiftRegister shiftRegister, byte data);
/**
* @brief Enable output DataPosition
@@ 362,9 373,9 @@ extern void avr_sipo_shift_register_write_byte(ShiftRegisterHandle shiftRegister
* This function enables the output so the shift register
* outputs the data shifted in it.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_enable_output(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_enable_output(const SipoShiftRegister shiftRegister);
/**
* @brief Disable output DataPosition
@@ 372,9 383,9 @@ extern void avr_sipo_shift_register_enable_output(ShiftRegisterHandle shiftRegis
* This function disables the output so the shift register
* doesn't output anything.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_disable_output(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_disable_output(const SipoShiftRegister shiftRegister);
/**
* @brief Psuh data to output
@@ 383,9 394,9 @@ extern void avr_sipo_shift_register_disable_output(ShiftRegisterHandle shiftRegi
* to the storage register. That means the data you shift
* in will be set only after you call this function.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_push_data_to_output(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_push_data_to_output(const SipoShiftRegister shiftRegister);
/**
* @brief Disable and enable clock to reset the SR value
@@ 394,8 405,8 @@ extern void avr_sipo_shift_register_push_data_to_output(ShiftRegisterHandle shif
* and enables the clock. Doing that the register will
* be reset.
*
- * @param shiftRegisterHandle
+ * @param shiftRegister
*/
-extern void avr_sipo_shift_register_reset(ShiftRegisterHandle shiftRegisterHandle);
+extern void avr_sipo_shift_register_reset(const SipoShiftRegister shiftRegister);
#endif=
\ No newline at end of file
M src/sr/shift_register.c => src/sr/shift_register.c +17 -19
@@ 3,32 3,30 @@
#include <util/delay.h>
#include <stdlib.h>
-void avr_shift_register_destroy(ShiftRegisterHandle shiftRegisterHandle)
+const ShiftRegister avr_shift_register_create(
+ ShiftRegisterTypeHeader type,
+ const DataPosition clockEnable,
+ const DataPosition clockPulse,
+ int waitTime
+)
{
- free((ShiftRegister*) shiftRegisterHandle);
+ ShiftRegister sr = { type, clockEnable, clockPulse, waitTime };
+ return sr;
}
-void avr_shift_register_clock_pulse(ShiftRegisterHandle shiftRegisterHandle)
-{
- ShiftRegister* sr = (ShiftRegister*) shiftRegisterHandle;
-
- data_position_set_port(sr->clockPulse);
- _delay_ms(1);
- data_position_reset_port(sr->clockPulse);
+void avr_shift_register_clock_pulse(ShiftRegister shiftRegister)
+{
+ data_position_set_port(shiftRegister.clockPulse);
+ sleep(shiftRegister.waitTime);
+ data_position_reset_port(shiftRegister.clockPulse);
}
-void avr_shift_register_enable_clock(ShiftRegisterHandle shiftRegisterHandle)
+void avr_shift_register_enable_clock(ShiftRegister shiftRegister)
{
- ShiftRegister* sr = (ShiftRegister*) shiftRegisterHandle;
- data_position_set_port(sr->clockEnable);
-
- sr->clockEnabled = 1;
+ data_position_set_port(shiftRegister.clockEnable);
}
-void avr_shift_register_disable_clock(ShiftRegisterHandle shiftRegisterHandle)
+void avr_shift_register_disable_clock(ShiftRegister shiftRegister)
{
- ShiftRegister* sr = (ShiftRegister*) shiftRegisterHandle;
- data_position_reset_port(sr->clockEnable);
-
- sr->clockEnabled = 0;
+ data_position_reset_port(shiftRegister.clockEnable);
}=
\ No newline at end of file
M src/sr/shift_register_internal.h => src/sr/shift_register_internal.h +1 -29
@@ 8,34 8,6 @@ void set_value(volatile byte* reg, byte position);
void reset_value(volatile byte* reg, byte position);
bool get_value(volatile byte* reg, byte position);
-typedef enum {
- SR_PISO,
- SR_SIPO
-} ShiftRegisterTypeHeader;
-
-typedef struct {
- ShiftRegisterTypeHeader type;
-} ShiftRegisterHeader;
-
-typedef struct {
- ShiftRegisterHeader header;
- const DataPosition* clockEnable;
- const DataPosition* clockPulse;
- int waitTime;
- bool clockEnabled;
-} ShiftRegister;
-
-typedef struct {
- ShiftRegister shiftRegister;
- const DataPosition* output;
- const DataPosition* parallelLoad;
-} PisoShiftRegister;
-
-typedef struct {
- ShiftRegister shiftRegister;
- const DataPosition* input;
- const DataPosition* outputEnable;
- const DataPosition* pushOutput;
-} SipoShiftRegister;
+void sleep(byte milliseconds);
#endif=
\ No newline at end of file
M src/sr/sipo_shift_register.c => src/sr/sipo_shift_register.c +37 -55
@@ 2,94 2,76 @@
#include <util/delay.h>
#include <stdlib.h>
-ShiftRegisterHandle avr_sipo_shift_register_create(
- const DataPosition* clockEnable,
- const DataPosition* clockPulse,
- const DataPosition* input,
- const DataPosition* outputEnable,
- const DataPosition* pushOutput,
+const SipoShiftRegister avr_sipo_shift_register_create(
+ const DataPosition clockEnable,
+ const DataPosition clockPulse,
+ const DataPosition input,
+ const DataPosition outputEnable,
+ const DataPosition pushOutput,
int waitTime
)
{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) malloc(sizeof(SipoShiftRegister));
-
- shiftRegister->input = input;
- shiftRegister->outputEnable = outputEnable;
- shiftRegister->pushOutput = pushOutput;
- shiftRegister->shiftRegister.clockEnable = clockEnable;
- shiftRegister->shiftRegister.clockPulse = clockPulse;
-
- return shiftRegister;
+ const ShiftRegister shiftRegister = avr_shift_register_create(SR_SIPO, clockEnable, clockPulse, waitTime);
+ SipoShiftRegister sipoShiftRegister = { shiftRegister, input, outputEnable, pushOutput };
+ return sipoShiftRegister;
}
-void avr_sipo_shift_register_init(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_init(const SipoShiftRegister shiftRegister)
{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) shiftRegisterHandle;
-
- data_position_set_ddr(shiftRegister->input);
- data_position_set_ddr(shiftRegister->outputEnable);
- data_position_set_ddr(shiftRegister->pushOutput);
- data_position_set_ddr(shiftRegister->shiftRegister.clockPulse);
- data_position_set_ddr(shiftRegister->shiftRegister.clockEnable);
-
- avr_sipo_shift_register_disable_output(shiftRegisterHandle);
- avr_shift_register_enable_clock(shiftRegisterHandle);
+ data_position_set_ddr(shiftRegister.input);
+ data_position_set_ddr(shiftRegister.outputEnable);
+ data_position_set_ddr(shiftRegister.pushOutput);
+ data_position_set_ddr(shiftRegister.shiftRegister.clockPulse);
+ data_position_set_ddr(shiftRegister.shiftRegister.clockEnable);
+
+ avr_sipo_shift_register_disable_output(shiftRegister);
+ avr_shift_register_enable_clock(shiftRegister.shiftRegister);
}
-void avr_sipo_shift_register_destroy(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_shift(const SipoShiftRegister shiftRegister)
{
- free((SipoShiftRegister *) shiftRegisterHandle);
+ avr_shift_register_clock_pulse(shiftRegister.shiftRegister);
}
-void avr_sipo_shift_register_shift(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_write_bit(const SipoShiftRegister shiftRegister, byte data, int position)
{
- avr_shift_register_clock_pulse(shiftRegisterHandle);
-}
-
-void avr_sipo_shift_register_write_bit(ShiftRegisterHandle shiftRegisterHandle, byte data, int position)
-{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) shiftRegisterHandle;
-
data &= (1 << position);
if (data > 0) {
- data_position_set_port(shiftRegister->input);
+ data_position_set_port(shiftRegister.input);
} else {
- data_position_reset_port(shiftRegister->input);
+ data_position_reset_port(shiftRegister.input);
}
- avr_sipo_shift_register_shift(shiftRegisterHandle);
+ avr_sipo_shift_register_shift(shiftRegister);
}
-void avr_sipo_shift_register_write_byte(ShiftRegisterHandle shiftRegisterHandle, byte data)
+void avr_sipo_shift_register_write_byte(const SipoShiftRegister shiftRegister, byte data)
{
for (int i = 0; i < 8; i++)
{
- avr_sipo_shift_register_write_bit(shiftRegisterHandle, data, i);
+ avr_sipo_shift_register_write_bit(shiftRegister, data, i);
}
}
-void avr_sipo_shift_register_enable_output(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_enable_output(const SipoShiftRegister shiftRegister)
{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) shiftRegisterHandle;
- data_position_reset_port(shiftRegister->outputEnable);
+ data_position_reset_port(shiftRegister.outputEnable);
}
-void avr_sipo_shift_register_disable_output(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_disable_output(const SipoShiftRegister shiftRegister)
{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) shiftRegisterHandle;
- data_position_set_port(shiftRegister->outputEnable);
+ data_position_set_port(shiftRegister.outputEnable);
}
-void avr_sipo_shift_register_push_data_to_output(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_push_data_to_output(const SipoShiftRegister shiftRegister)
{
- SipoShiftRegister* shiftRegister = (SipoShiftRegister*) shiftRegisterHandle;
- data_position_set_port(shiftRegister->pushOutput);
+ data_position_set_port(shiftRegister.pushOutput);
}
-void avr_sipo_shift_register_reset(ShiftRegisterHandle shiftRegisterHandle)
+void avr_sipo_shift_register_reset(const SipoShiftRegister shiftRegister)
{
- avr_shift_register_disable_clock(shiftRegisterHandle);
- _delay_ms(1);
- avr_shift_register_enable_clock(shiftRegisterHandle);
-}
+ avr_shift_register_disable_clock(shiftRegister.shiftRegister);
+ sleep(shiftRegister.shiftRegister.waitTime);
+ avr_shift_register_enable_clock(shiftRegister.shiftRegister);
+}<
\ No newline at end of file
M src/sr/util.c => src/sr/util.c +32 -0
@@ 1,4 1,6 @@
#include "shift_register_internal.h"
+#include <stdio.h>
+#include <util/delay.h>
void set_value_to(volatile byte* reg, byte position, byte value)
{
@@ 22,4 24,34 @@ void reset_value(volatile byte* reg, byte position)
bool get_value(volatile byte* reg, byte position)
{
return (*reg & (1 << position)) >> position;
+}
+
+void sleep(byte milliseconds)
+{
+ if (milliseconds % 10 == 0) {
+ while (milliseconds > 0) {
+ _delay_ms(10);
+ milliseconds -= 10;
+ }
+ } else if (milliseconds % 5 == 0) {
+ while (milliseconds > 0) {
+ _delay_ms(5);
+ milliseconds -= 5;
+ }
+ } else if (milliseconds % 4 == 0) {
+ while (milliseconds > 0) {
+ _delay_ms(4);
+ milliseconds -= 4;
+ }
+ } else if (milliseconds % 2 == 0) {
+ while (milliseconds > 0) {
+ _delay_ms(2);
+ milliseconds -= 2;
+ }
+ } else {
+ while (milliseconds > 0) {
+ _delay_ms(1);
+ milliseconds -= 1;
+ }
+ }
}=
\ No newline at end of file