-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #568 from Paciente8159/74hc595-pio
RP2040 custom 74hc595 via PIO
- Loading branch information
Showing
6 changed files
with
217 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
; | ||
;Name: ic74hc595.pio | ||
;Description: Implements a custom PIO for 74HC595 shift register in µCNC for RP2040. | ||
; | ||
;Copyright: Copyright (c) João Martins | ||
;Author: João Martins | ||
;Date: 02-11-2023 | ||
; | ||
;µCNC is free software: you can redistribute it and/or modify | ||
;it under the terms of the GNU General Public License as published by | ||
;the Free Software Foundation, either version 3 of the License, or | ||
;(at your option) any later version. Please see <http://www.gnu.org/licenses/> | ||
; | ||
;µCNC is distributed WITHOUT ANY WARRANTY; | ||
;Also without the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
;See the GNU General Public License for more details. | ||
; | ||
|
||
.program ic74hc595 | ||
.side_set 1 opt | ||
|
||
pull ; shift TX to OSR | ||
set x, 31 ; load loop counter | ||
set pins, 0 ; set all pins low (latch) | ||
bitloop: ; loop bits | ||
out pins, 1 side 0 ; Shift 1 bit from OSR to the data pin and the remaining down | ||
jmp x-- bitloop side 1 ; decrement loop and bring clock up | ||
set pins, 2 ; set 3rd pin (4=0b100) up (latch) | ||
|
||
% c-sdk { | ||
#include "hardware/clocks.h" | ||
|
||
static inline void ic74hc595_program_init(PIO pio, uint sm, uint offset, uint pin_data, uint pin_clk, uint pin_latch, uint freq) { | ||
pio_sm_config c = ic74hc595_program_get_default_config(offset); | ||
sm_config_set_out_pins(&c, pin_data, 1); // define one pin to respond to the out instruction | ||
sm_config_set_set_pins(&c, pin_clk, 2); // define all pins to respond to the set instruction | ||
sm_config_set_sideset_pins(&c, pin_clk); // define clock as the side set base pin (and only) | ||
// Only support MSB-first in this example code (shift to left, no auto push/pull, threshold=nbits) | ||
sm_config_set_out_shift(&c, false, false, 32); | ||
// All pins output | ||
pio_sm_set_consecutive_pindirs(pio, sm, pin_data, 3, true); | ||
pio_gpio_init(pio, pin_data); | ||
pio_gpio_init(pio, pin_clk); | ||
pio_gpio_init(pio, pin_latch); | ||
// We only need TX, so get an 8-deep FIFO! | ||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); | ||
// SM transmits 1 bit per 8 execution cycles. | ||
float div = (float)clock_get_hz(clk_sys) / (freq << 1); | ||
sm_config_set_clkdiv(&c, div); | ||
pio_sm_init(pio, sm, offset, &c); | ||
pio_sm_set_enabled(pio, sm, true); | ||
} | ||
|
||
static inline void ic74hc595_program_write(PIO pio, uint sm, uint out) { | ||
pio_sm_put_blocking(pio, sm, out); | ||
} | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// -------------------------------------------------- // | ||
// This file is autogenerated by pioasm; do not edit! // | ||
// -------------------------------------------------- // | ||
|
||
#pragma once | ||
|
||
#if !PICO_NO_HARDWARE | ||
#include "hardware/pio.h" | ||
#endif | ||
|
||
// --------- // | ||
// ic74hc595 // | ||
// --------- // | ||
|
||
#define ic74hc595_wrap_target 0 | ||
#define ic74hc595_wrap 5 | ||
|
||
static const uint16_t ic74hc595_program_instructions[] = { | ||
// .wrap_target | ||
0x80a0, // 0: pull block | ||
0xe03f, // 1: set x, 31 | ||
0xe000, // 2: set pins, 0 | ||
0x7001, // 3: out pins, 1 side 0 | ||
0x1843, // 4: jmp x--, 3 side 1 | ||
0xe002, // 5: set pins, 2 | ||
// .wrap | ||
}; | ||
|
||
#if !PICO_NO_HARDWARE | ||
static const struct pio_program ic74hc595_program = { | ||
.instructions = ic74hc595_program_instructions, | ||
.length = 6, | ||
.origin = -1, | ||
}; | ||
|
||
static inline pio_sm_config ic74hc595_program_get_default_config(uint offset) { | ||
pio_sm_config c = pio_get_default_sm_config(); | ||
sm_config_set_wrap(&c, offset + ic74hc595_wrap_target, offset + ic74hc595_wrap); | ||
sm_config_set_sideset(&c, 2, true, false); | ||
return c; | ||
} | ||
|
||
#include "hardware/clocks.h" | ||
static inline void ic74hc595_program_init(PIO pio, uint sm, uint offset, uint pin_data, uint pin_clk, uint pin_latch, uint freq) { | ||
pio_sm_config c = ic74hc595_program_get_default_config(offset); | ||
sm_config_set_out_pins(&c, pin_data, 1); // define one pin to respond to the out instruction | ||
sm_config_set_set_pins(&c, pin_clk, 2); // define all pins to respond to the set instruction | ||
sm_config_set_sideset_pins(&c, pin_clk); // define clock as the side set base pin (and only) | ||
// Only support MSB-first in this example code (shift to left, no auto push/pull, threshold=nbits) | ||
sm_config_set_out_shift(&c, false, false, 32); | ||
// All pins output | ||
pio_sm_set_consecutive_pindirs(pio, sm, pin_data, 3, true); | ||
pio_gpio_init(pio, pin_data); | ||
pio_gpio_init(pio, pin_clk); | ||
pio_gpio_init(pio, pin_latch); | ||
// We only need TX, so get an 8-deep FIFO! | ||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); | ||
// SM transmits 1 bit per 8 execution cycles. | ||
float div = (float)clock_get_hz(clk_sys) / (freq << 1); | ||
sm_config_set_clkdiv(&c, div); | ||
pio_sm_init(pio, sm, offset, &c); | ||
pio_sm_set_enabled(pio, sm, true); | ||
} | ||
static inline void ic74hc595_program_write(PIO pio, uint sm, uint out) { | ||
pio_sm_put_blocking(pio, sm, out); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters