kopia lustrzana https://github.com/oddwires/RP2040-code
Improved Phase Lock
rodzic
2f277b4448
commit
17c262526c
|
@ -31,6 +31,7 @@ void pio_DAC_program_init(PIO pio, uint sm, uint offset, uint start_pin) {
|
||||||
pio_sm_config c = pio_DAC_program_get_default_config(offset); // Define PIO Configuration structure
|
pio_sm_config c = pio_DAC_program_get_default_config(offset); // Define PIO Configuration structure
|
||||||
sm_config_set_out_pins(&c, start_pin, 8); // Configure pins to be targeted by the OUT (and MOV) commands
|
sm_config_set_out_pins(&c, start_pin, 8); // Configure pins to be targeted by the OUT (and MOV) commands
|
||||||
sm_config_set_out_shift(&c, true, true, 8); // Shift right, Autopull enabled, 6/8 bits
|
sm_config_set_out_shift(&c, true, true, 8); // Shift right, Autopull enabled, 6/8 bits
|
||||||
|
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); // Set TX_FIFO to 8. Improves stability at high frequencies
|
||||||
pio_sm_init(pio, sm, offset, &c); // Load configuration and jump to start of the program
|
pio_sm_init(pio, sm, offset, &c); // Load configuration and jump to start of the program
|
||||||
pio_sm_set_enabled(pio, sm, true);
|
pio_sm_set_enabled(pio, sm, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// TBD: 1) SPI read connecton
|
||||||
|
// 2) Capacitors on op-amps
|
||||||
|
// 3) Issue with phase lock - red/writes to serial port affecting phase lock at high frequencies
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -9,7 +13,6 @@
|
||||||
#include "hardware/dma.h"
|
#include "hardware/dma.h"
|
||||||
#include "blink.pio.h"
|
#include "blink.pio.h"
|
||||||
#include "DAC.pio.h"
|
#include "DAC.pio.h"
|
||||||
|
|
||||||
#include "hardware/gpio.h" // Required for manually toggling GPIO pins (clock)
|
#include "hardware/gpio.h" // Required for manually toggling GPIO pins (clock)
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
@ -53,17 +56,25 @@
|
||||||
//#define SysClock 250 // System clock x 2 for 0.977 MHz DAC output
|
//#define SysClock 250 // System clock x 2 for 0.977 MHz DAC output
|
||||||
#define SysClock 280 // Overclock for 1.000 MHz DAC output
|
#define SysClock 280 // Overclock for 1.000 MHz DAC output
|
||||||
|
|
||||||
// Data for clock face generated by Excel spreadsheet...
|
// Data for the clock face is generated externally using an Excel spreadsheet...
|
||||||
uint8_t FaceX[] = {235,239,243,247,251,255,255,254,254,254,254,254,254,254,253,253,253,252,252,251,251,250,250,249,248,248,247,246,245,244,244,243,242,241,240,239,221,224,227,231,234,238,236,235,234,233,232,230,229,228,226,225,224,222,221,219,218,216,214,213,211,209,208,206,204,203,201,199,197,195,193,182,184,186,188,190,191,190,188,186,184,182,180,178,176,174,172,170,167,165,163,161,159,157,155,153,150,148,146,144,142,139,137,135,133,131,128,128,128,128,128,128,126,124,122,120,117,115,113,111,109,107,104,102,100,98,96,94,92,90,87,85,83,81,79,77,75,73,71,69,67,75,73,71,69,67,65,64,62,60,58,56,54,53,51,49,47,46,44,43,41,39,38,36,35,33,32,31,29,28,27,25,24,23,22,20,36,33,30,26,23,19,18,17,16,15,14,13,12,12,11,10,9,9,8,7,7,6,6,5,5,4,4,4,3,3,3,3,3,3,2,22,18,14,10,6,2,2,3,3,3,3,3,3,4,4,4,5,5,6,6,7,7,8,9,9,10,11,12,12,13,14,15,16,17,18,36,33,30,26,23,19,20,22,23,24,25,27,28,29,31,32,33,35,36,38,39,41,43,44,46,47,49,51,53,54,56,58,60,62,64,75,73,71,69,67,65,67,69,71,73,75,77,79,81,83,85,87,90,92,94,96,98,100,102,
|
uint8_t FaceX[] = {
|
||||||
104,107,109,111,113,115,117,120,122,124,126,128,128,128,128,128,128,131,133,135,137,139,142,144,146,148,150,153,155,157,159,161,163,165,167,170,172,174,176,178,180,182,184,186,188,190,182,184,186,188,190,191,193,195,197,199,201,203,204,206,208,209,211,213,214,216,218,219,221,222,224,225,226,228,229,230,232,233,234,235,236,221,224,227,231,234,238,239,240,241,242,243,244,244,245,246,247,248,248,249,250,250,251,251,252,252,253,253,253,254,254,254,254,254,254,254} ;
|
0xfa,0xfb,0xfc,0xfd,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfc,0xfc,0xfb,0xfb,0xfa,0xfa,0xf9,0xf8,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf3,0xf2,0xf1,0xf0,0xef,0xe9,0xea,0xeb,0xec,0xed,0xed,0xec,0xeb,0xea,0xe9,0xe7,0xe6,0xe5,0xe3,0xe2,0xe1,0xdf,0xde,0xdc,0xdb,0xd9,0xd8,0xd6,0xd4,0xd3,0xd1,0xcf,0xcd,0xcc,0xca,0xc8,0xc6,0xc4,0xc3,0xc1,0xbc,0xbd,0xbd,0xbe,0xbe,0xbf,0xbd,0xbb,0xb9,0xb7,0xb5,0xb3,0xb1,0xaf,0xad,0xab,0xa9,0xa6,0xa4,0xa2,0xa0,0x9e,0x9c,0x9a,0x97,0x95,0x93,0x91,0x8f,0x8c,0x8a,0x88,0x86,0x83,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x7b,0x78,0x76,0x74,0x72,0x6f,0x6d,0x6b,0x69,0x67,0x64,0x62,0x60,0x5e,0x5c,0x5a,0x58,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,0x45,0x43,0x41,0x42,0x41,0x41,0x40,0x40,0x3f,0x3d,0x3b,0x3a,0x38,0x36,0x34,0x32,0x31,0x2f,0x2d,0x2b,0x2a,0x28,0x26,0x25,0x23,0x22,0x20,0x1f,0x1d,0x1c,0x1b,0x19,0x18,0x17,0x15,0x14,0x13,0x12,0x15,0x14,0x13,0x12,0x11,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0b,0x0a,0x09,0x08,0x07,0x06,0x06,0x05,0x04,0x04,0x03,0x03,0x02,
|
||||||
uint8_t FaceY[] = {128,128,128,128,128,128,128,126,124,122,120,117,115,113,111,109,107,104,102,100,98,96,94,92,90,87,85,83,81,79,77,75,73,71,69,67,75,73,71,69,67,65,64,62,60,58,56,54,53,51,49,47,46,44,43,41,39,38,36,35,33,32,31,29,28,27,25,24,23,22,20,36,33,30,26,23,19,18,17,16,15,14,13,12,12,11,10,9,9,8,7,7,6,6,5,5,4,4,4,3,3,3,3,3,3,2,22,18,14,10,6,2,2,3,3,3,3,3,3,4,4,4,5,5,6,6,7,7,8,9,9,10,11,12,12,13,14,15,16,17,18,36,33,30,26,23,19,20,22,23,24,25,27,28,29,31,32,33,35,36,38,39,41,43,44,46,47,49,51,53,54,56,58,60,62,64,75,73,71,69,67,65,67,69,71,73,75,77,79,81,83,85,87,90,92,94,96,98,100,102,104,107,109,111,113,115,117,120,122,124,126,128,128,128,128,128,128,131,133,135,137,139,142,144,146,148,150,153,155,157,159,161,163,165,167,170,172,174,176,178,180,182,184,186,188,190,182,184,186,188,190,191,193,195,197,199,201,203,204,206,208,209,211,213,214,216,218,219,221,222,224,225,226,228,229,230,232,233,234,235,236,221,224,227,231,234,238,239,240,241,242,243,244,244,245,246,247,248,248,249,250,250,251,251,252,
|
0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0b,0x0c,0x0d,0x0e,0x0f,0x15,0x14,0x13,0x12,0x11,0x11,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1b,0x1c,0x1d,0x1f,0x20,0x22,0x23,0x25,0x26,0x28,0x2a,0x2b,0x2d,0x2f,0x31,0x32,0x34,0x36,0x38,0x3a,0x3b,0x3d,0x42,0x41,0x41,0x40,0x40,0x3f,0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f,0x51,0x53,0x55,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,0x67,0x69,0x6b,0x6d,0x6f,0x72,0x74,0x76,0x78,0x7b,0x7d,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x81,0x83,0x86,0x88,0x8a,0x8c,0x8f,0x91,0x93,0x95,0x97,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa9,0xab,0xad,0xaf,0xb1,0xb3,0xb5,0xb7,0xb9,0xbb,0xbd,0xbc,0xbd,0xbd,0xbe,0xbe,0xbf,0xc1,0xc3,0xc4,0xc6,0xc8,0xca,0xcc,0xcd,0xcf,0xd1,0xd3,0xd4,0xd6,0xd8,0xd9,0xdb,0xdc,0xde,0xdf,0xe1,0xe2,0xe3,0xe5,0xe6,0xe7,0xe9,0xea,0xeb,0xec,0xe9,0xea,0xeb,0xec,0xed,0xed,0xef,0xf0,0xf1,0xf2,0xf3,0xf3,0xf4,0xf5,
|
||||||
252,253,253,253,254,254,254,254,254,254,254,235,239,243,247,251,255,254,254,254,254,254,254,254,253,253,253,252,252,251,251,250,250,249,248,248,247,246,245,244,244,243,242,241,240,239,221,224,227,231,234,238,236,235,234,233,232,230,229,228,226,225,224,222,221,219,218,216,214,213,211,209,208,206,204,203,201,199,197,195,193,182,184,186,188,190,191,190,188,186,184,182,180,178,176,174,172,170,167,165,163,161,159,157,155,153,150,148,146,144,142,139,137,135,133,131} ;
|
0xf6,0xf7,0xf8,0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x0e,0x0d,0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x52,0x51,0x50,0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x46,0x46,0x46,0x46,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,
|
||||||
// (Number of pixels: 421)
|
0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x50,0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x82,0x81,0x80,0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xe0,0xe1,0xe2,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe2,0xe1,0xe0,0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,0xe1,0xe2,0xe3,0xe3,0xe3,0xe3,0xe2,0xe1,0xe0,0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd7,0xd7,0xd7,0xd8,0xd9,0xf0,0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
|
||||||
|
0xeb,0xec,0xed,0xee,0xef,0xf0,0xf0,0xf0,0xf0,0xf0,0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x81,0x80,0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x75,0x75,0x75,0x75,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x80,0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,} ;
|
||||||
|
uint8_t FaceY[] = {
|
||||||
|
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x7b,0x78,0x76,0x74,0x72,0x6f,0x6d,0x6b,0x69,0x67,0x64,0x62,0x60,0x5e,0x5c,0x5a,0x58,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,0x45,0x43,0x41,0x42,0x41,0x41,0x40,0x40,0x3f,0x3d,0x3b,0x3a,0x38,0x36,0x34,0x32,0x31,0x2f,0x2d,0x2b,0x2a,0x28,0x26,0x25,0x23,0x22,0x20,0x1f,0x1d,0x1c,0x1b,0x19,0x18,0x17,0x15,0x14,0x13,0x12,0x15,0x14,0x13,0x12,0x11,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0b,0x0a,0x09,0x08,0x07,0x06,0x06,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0b,0x0c,0x0d,0x0e,0x0f,0x15,0x14,0x13,0x12,0x11,0x11,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1b,0x1c,0x1d,0x1f,0x20,0x22,0x23,0x25,0x26,0x28,0x2a,0x2b,0x2d,0x2f,0x31,0x32,0x34,0x36,0x38,0x3a,0x3b,0x3d,0x42,0x41,0x41,0x40,0x40,0x3f,0x41,0x43,0x45,0x47,0x49,0x4b,0x4d,0x4f,0x51,0x53,0x55,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,
|
||||||
|
0x67,0x69,0x6b,0x6d,0x6f,0x72,0x74,0x76,0x78,0x7b,0x7d,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x81,0x83,0x86,0x88,0x8a,0x8c,0x8f,0x91,0x93,0x95,0x97,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa9,0xab,0xad,0xaf,0xb1,0xb3,0xb5,0xb7,0xb9,0xbb,0xbd,0xbc,0xbd,0xbd,0xbe,0xbe,0xbf,0xc1,0xc3,0xc4,0xc6,0xc8,0xca,0xcc,0xcd,0xcf,0xd1,0xd3,0xd4,0xd6,0xd8,0xd9,0xdb,0xdc,0xde,0xdf,0xe1,0xe2,0xe3,0xe5,0xe6,0xe7,0xe9,0xea,0xeb,0xec,0xe9,0xea,0xeb,0xec,0xed,0xed,0xef,0xf0,0xf1,0xf2,0xf3,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfc,0xfc,0xfb,0xfb,0xfa,0xfa,0xf9,0xf8,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf3,0xf2,0xf1,0xf0,0xef,0xe9,0xea,0xeb,0xec,0xed,0xed,0xec,0xeb,0xea,0xe9,0xe7,0xe6,0xe5,0xe3,0xe2,0xe1,0xdf,0xde,0xdc,0xdb,0xd9,0xd8,0xd6,0xd4,0xd3,0xd1,0xcf,0xcd,0xcc,0xca,0xc8,0xc6,0xc4,0xc3,0xc1,0xbc,0xbd,0xbd,0xbe,0xbe,0xbf,0xbd,0xbb,0xb9,0xb7,0xb5,0xb3,0xb1,0xaf,
|
||||||
|
0xad,0xab,0xa9,0xa6,0xa4,0xa2,0xa0,0x9e,0x9c,0x9a,0x97,0x95,0x93,0x91,0x8f,0x8c,0x8a,0x88,0x86,0x83,0x81,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x3e,0x3d,0x3c,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x78,0x77,0x76,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x88,0x87,0x86,0xb3,0xb2,0xb1,0xb0,0xaf,0xae,0xad,0xac,0xab,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xe2,0xe3,0xe4,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,
|
||||||
|
0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xe0,0xdf,0xde,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xde,0xdf,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe7,0xe8,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb2,0xb1,0xb0,0xaf,0xae,0xad,0xac,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0x87,0x88,0x89,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80,0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x76,0x76,0x76,
|
||||||
|
0x76,0x76,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f,0x7e,0x7d,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x4d,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x0e,0x0d,0x0c,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,} ;
|
||||||
|
// (Number of pixels: 1000)
|
||||||
|
|
||||||
// Store clock hands co-ordinates...
|
// Store clock hands co-ordinates...
|
||||||
uint8_t HandsX[192] = {} ; // Each hand requires 64 bytes - 3x64=192
|
uint8_t HandsX[192] = {} ; // Each hand requires 64 bytes - 3x64=192
|
||||||
uint8_t HandsY[192] = {} ;
|
uint8_t HandsY[192] = {} ;
|
||||||
int Hours=0, Mins=0, Secs=0, Angle, StartX, StartY, Radius ;
|
int Hours=0, Mins=0, Secs=0, LEDCtr=0, Angle, StartX, StartY, Radius ;
|
||||||
float Radians ;
|
float Radians ;
|
||||||
|
|
||||||
int tmp ;
|
int tmp ;
|
||||||
|
@ -129,32 +140,14 @@ public:
|
||||||
MarginCount = 0 ;
|
MarginCount = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setter functions...
|
|
||||||
void ReInit () {
|
|
||||||
// Re-initialises DMA channels to their initial state.
|
|
||||||
// Note: 1) DMA channels are not restarted, allowing for atomic (simultaneous) restart of both DAC channels later.
|
|
||||||
// 2) Cannot use dma_hw->abort on chained DMA channels, so using disable and re-enable instead.
|
|
||||||
// 3) This needs to be performed across both DAC channels to ensure phase sync is maintained.
|
|
||||||
// Disable both DMA channels associated with this DAC...
|
|
||||||
hw_clear_bits(&dma_hw->ch[data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
|
||||||
hw_clear_bits(&dma_hw->ch[ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
|
||||||
// Reset the data transfer DMA's to the start of the data Bitmap...
|
|
||||||
dma_channel_set_read_addr(data_chan, &DAC_data[0], false);
|
|
||||||
// Re-enable both DMA channels associated with this DAC...
|
|
||||||
hw_set_bits(&dma_hw->ch[data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
|
||||||
hw_set_bits(&dma_hw->ch[ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Set(int _type, int _val) {
|
int Set(int _type, int _val) {
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case _Freq_:
|
case _Freq_:
|
||||||
Freq = _val ; // Frequency (numeric)
|
Freq = _val ; // Frequency (numeric)
|
||||||
ReInit() ; // Stop and reset the DAC channel (no restart)
|
|
||||||
DACspeed(Freq * Range) ; // Update State machine run speed
|
DACspeed(Freq * Range) ; // Update State machine run speed
|
||||||
break ;
|
break ;
|
||||||
case _Phase_:
|
case _Phase_:
|
||||||
Phase = _val ; // Phase shift (0->355 degrees)
|
Phase = _val ; // Phase shift (0->355 degrees)
|
||||||
ReInit() ; // Stop and reset the DAC channel (no restart)
|
|
||||||
DataCalc() ; // Recalc Bitmap and apply new phase value
|
DataCalc() ; // Recalc Bitmap and apply new phase value
|
||||||
break ;
|
break ;
|
||||||
case _Level_:
|
case _Level_:
|
||||||
|
@ -398,31 +391,20 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class blink_forever { // Class to initialise a state machine to blink a GPIO pin
|
|
||||||
PIO pio ; // Class wide variables to share value with setter function
|
|
||||||
public:
|
|
||||||
uint pioNum, StateMachine, Freq, _offset ;
|
|
||||||
blink_forever(PIO _pio) {
|
|
||||||
pio = _pio; // transfer parameter to class wide var
|
|
||||||
pioNum = pio_get_index(_pio);
|
|
||||||
StateMachine = pio_claim_unused_sm(_pio, true); // Find a free state machine on the specified PIO - error if there are none.
|
|
||||||
_offset = pio_add_program(_pio, &pio_blink_program);
|
|
||||||
blink_program_init(_pio, StateMachine, _offset, PICO_DEFAULT_LED_PIN );
|
|
||||||
pio_sm_set_enabled(_pio, StateMachine, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setter function...
|
|
||||||
void Set_Frequency(int _frequency){
|
|
||||||
Freq = _frequency; // Copy parm to class var
|
|
||||||
// Frequency scaled by 2000 as blink.pio requires this number of cycles to complete...
|
|
||||||
float DAC_div = (float)clock_get_hz(clk_sys) /((float)_frequency*2000);
|
|
||||||
pio_sm_set_clkdiv(pio, StateMachine, DAC_div); // Set the State Machine clock speed
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Repeating_Timer_Callback(struct repeating_timer *t) {
|
bool Repeating_Timer_Callback(struct repeating_timer *t) {
|
||||||
|
// Routine called 5 times per second...
|
||||||
int i, steps=64, MidX=128, MidY=128 ;
|
int i, steps=64, MidX=128, MidY=128 ;
|
||||||
// Bump the time...
|
// printf("%d\n",LEDCtr) ; // Debug
|
||||||
|
LEDCtr -- ;
|
||||||
|
if (LEDCtr>0) {
|
||||||
|
// LED off, and no change to the time for 4 out of 5 cycles...
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 0); // LED is connected to PICO_DEFAULT_LED_PIN
|
||||||
|
} else {
|
||||||
|
// Falls through here once per second.
|
||||||
|
LEDCtr = 5 ;
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 1); // LED is connected to PICO_DEFAULT_LED_PIN
|
||||||
|
|
||||||
|
// Bump the clock...
|
||||||
if ((++Secs)>59) Secs=0 ; // Always bump seconds
|
if ((++Secs)>59) Secs=0 ; // Always bump seconds
|
||||||
if (Secs==0) { if ((++Mins)>59 ) Mins=0 ; } // Bump minutes when seconds = 0
|
if (Secs==0) { if ((++Mins)>59 ) Mins=0 ; } // Bump minutes when seconds = 0
|
||||||
if ((Mins==0) && (Secs==0)) { if ((++Hours)>24) Hours=0 ; } // Bump hours when minutes and seconds = 0
|
if ((Mins==0) && (Secs==0)) { if ((++Hours)>24) Hours=0 ; } // Bump hours when minutes and seconds = 0
|
||||||
|
@ -448,7 +430,7 @@ bool Repeating_Timer_Callback(struct repeating_timer *t) {
|
||||||
i++ ; }
|
i++ ; }
|
||||||
// Calculate hours hand...
|
// Calculate hours hand...
|
||||||
i=0, Radius=64 ; // Radius=Length of hours hand
|
i=0, Radius=64 ; // Radius=Length of hours hand
|
||||||
// Note: Hours hand progresses between hours in 5 partial increments, each measuring 12 minutes.
|
// Note: Hours hand progresses between hours in 5 partial increments, each increment measuring 12 minutes.
|
||||||
// Each 12 minute increment adds an additional 6 degrees of rotation to the hours hand.
|
// Each 12 minute increment adds an additional 6 degrees of rotation to the hours hand.
|
||||||
Angle=5*(270-(((Hours%12)*6)+(Mins/12)%5)) ; // Angle in degrees, shifted 90 degree anti-clockwise,
|
Angle=5*(270-(((Hours%12)*6)+(Mins/12)%5)) ; // Angle in degrees, shifted 90 degree anti-clockwise,
|
||||||
// and scaled by 5 to provide range 0=>12
|
// and scaled by 5 to provide range 0=>12
|
||||||
|
@ -460,7 +442,7 @@ bool Repeating_Timer_Callback(struct repeating_timer *t) {
|
||||||
i++ ; }
|
i++ ; }
|
||||||
|
|
||||||
// printf("%s%d:%d:%d - %d\n",MarginFW,Hours,Mins,Secs,tmp) ; // Debug
|
// printf("%s%d:%d:%d - %d\n",MarginFW,Hours,Mins,Secs,tmp) ; // Debug
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,11 +451,11 @@ void VerText () {
|
||||||
tmp = strlen(inStr) ; // Get number of command line characters
|
tmp = strlen(inStr) ; // Get number of command line characters
|
||||||
if (tmp != 0) tmp ++ ; // If there are characters, Bump to also allow for cursor
|
if (tmp != 0) tmp ++ ; // If there are characters, Bump to also allow for cursor
|
||||||
MarginVW[MWidth - tmp] = '\0' ; // Calculate padding required for command characters and cursor
|
MarginVW[MWidth - tmp] = '\0' ; // Calculate padding required for command characters and cursor
|
||||||
sprintf(ResultStr, "%s|--------------------|\n"
|
sprintf(ResultStr, "%s|---------------------|\n"
|
||||||
"%s| Function Generator |\n"
|
"%s| Function Generator |\n"
|
||||||
"%s| Version 1.0.0 |\n"
|
"%s| Version 1.0.0 |\n"
|
||||||
"%s| 11th August 2023 |\n"
|
"%s| 19th September 2023 |\n"
|
||||||
"%s|--------------------|\n",
|
"%s|---------------------|\n",
|
||||||
MarginVW, MarginFW, MarginFW, MarginFW, MarginFW ) ;
|
MarginVW, MarginFW, MarginFW, MarginFW, MarginFW ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,16 +494,18 @@ void HlpText () {
|
||||||
"%s<A/B/C>lennn - Level = nnn ( 0->100%%%% )\n"
|
"%s<A/B/C>lennn - Level = nnn ( 0->100%%%% )\n"
|
||||||
"%s<A/B/C>le+ - Level + 1\n"
|
"%s<A/B/C>le+ - Level + 1\n"
|
||||||
"%s<A/B/C>le- - Level - 1\n"
|
"%s<A/B/C>le- - Level - 1\n"
|
||||||
|
"%s<A/B/C>ti - Time mode (display analog clock)\n"
|
||||||
"%swhere...\n"
|
"%swhere...\n"
|
||||||
"%s<A/B/C> = DAC channel A,B or Both\n"
|
"%s<A/B/C> = DAC channel A,B or C=both\n"
|
||||||
"%snnn = Three digit numeric value\n",
|
"%snnn = Three digit numeric value\n",
|
||||||
MarginVW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
MarginVW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
||||||
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
||||||
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
||||||
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW ) ;
|
MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW, MarginFW,
|
||||||
|
MarginFW ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
void SysInfo (DAC DACobj[] ) {
|
||||||
// Print System Info and resource allocation detils, aligned to current margin settings...
|
// Print System Info and resource allocation detils, aligned to current margin settings...
|
||||||
// Note: 1) The following string requires '%%%%' to print '%' because...
|
// Note: 1) The following string requires '%%%%' to print '%' because...
|
||||||
// a) ResultStr is copied to outStr using sprintf - this reduces '%%%%' to '%%'
|
// a) ResultStr is copied to outStr using sprintf - this reduces '%%%%' to '%%'
|
||||||
|
@ -534,16 +518,10 @@ void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
||||||
sprintf(ResultStr,"%s|----------------------------------------------------------|\n"
|
sprintf(ResultStr,"%s|----------------------------------------------------------|\n"
|
||||||
"%s| System Info... |\n"
|
"%s| System Info... |\n"
|
||||||
"%s|----------------------------------------------------------|\n"
|
"%s|----------------------------------------------------------|\n"
|
||||||
|
"%s| Target board: Pico |\n"
|
||||||
"%s| RP2040 clock frequency: %7.3fMHz |\n"
|
"%s| RP2040 clock frequency: %7.3fMHz |\n"
|
||||||
"%s| Max DAC frequency: %7.3fMHz |\n"
|
"%s| Max DAC frequency: %7.3fMHz |\n"
|
||||||
"%s|----------------------------|-----------------------------|\n"
|
"%s|----------------------------|-----------------------------|\n"
|
||||||
"%s| LED blinker | |\n"
|
|
||||||
"%s|----------------------------| |\n"
|
|
||||||
"%s| PIO: %2d | |\n"
|
|
||||||
"%s| State machine: %2d | |\n"
|
|
||||||
"%s| GPIO: %2d | |\n"
|
|
||||||
"%s| Frequency: %2dHz | |\n"
|
|
||||||
"%s|----------------------------|-----------------------------|\n"
|
|
||||||
"%s| DAC Channel A | DAC Channel B |\n"
|
"%s| DAC Channel A | DAC Channel B |\n"
|
||||||
"%s|----------------------------|-----------------------------|\n"
|
"%s|----------------------------|-----------------------------|\n"
|
||||||
"%s| Level: %3d%%%% | Level: %3d%%%% |\n"
|
"%s| Level: %3d%%%% | Level: %3d%%%% |\n"
|
||||||
|
@ -553,15 +531,10 @@ void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
||||||
"%s| Duty cycle: %3d%%%% | Duty cycle: %3d%%%% |\n"
|
"%s| Duty cycle: %3d%%%% | Duty cycle: %3d%%%% |\n"
|
||||||
"%s| Sine harmonic: %1d | Sine harmonic: %1d |\n"
|
"%s| Sine harmonic: %1d | Sine harmonic: %1d |\n"
|
||||||
"%s| Triangle Rise: %3d%%%% | Triangle Rise: %3d%%%% |\n",
|
"%s| Triangle Rise: %3d%%%% | Triangle Rise: %3d%%%% |\n",
|
||||||
MarginVW, MarginFW, MarginFW,
|
MarginVW, MarginFW, MarginFW, MarginFW,
|
||||||
MarginFW, (float)clock_get_hz(clk_sys)/1000000,
|
MarginFW, (float)clock_get_hz(clk_sys)/1000000,
|
||||||
MarginFW, MaxDACfreq/1000000,
|
MarginFW, MaxDACfreq/1000000,
|
||||||
MarginFW, MarginFW, MarginFW,
|
MarginFW, MarginFW, MarginFW,
|
||||||
MarginFW, LED_blinky.pioNum,
|
|
||||||
MarginFW, LED_blinky.StateMachine,
|
|
||||||
MarginFW, PICO_DEFAULT_LED_PIN,
|
|
||||||
MarginFW, LED_blinky.Freq,
|
|
||||||
MarginFW, MarginFW, MarginFW,
|
|
||||||
MarginFW, DACobj[_DAC_A].Level, DACobj[_DAC_B].Level,
|
MarginFW, DACobj[_DAC_A].Level, DACobj[_DAC_B].Level,
|
||||||
MarginFW, DACobj[_DAC_A].Freq, DACobj[_DAC_B].Freq,
|
MarginFW, DACobj[_DAC_A].Freq, DACobj[_DAC_B].Freq,
|
||||||
MarginFW, DACobj[_DAC_A].Range, DACobj[_DAC_B].Range,
|
MarginFW, DACobj[_DAC_A].Range, DACobj[_DAC_B].Range,
|
||||||
|
@ -631,11 +604,6 @@ static void MCP41020_Write (uint8_t _ctrl, uint8_t _data) {
|
||||||
// Scale the data byte to be in the range 0->255.
|
// Scale the data byte to be in the range 0->255.
|
||||||
// Transmit data over the SPI bus to the Digi-Pot.
|
// Transmit data over the SPI bus to the Digi-Pot.
|
||||||
uint8_t buff[2];
|
uint8_t buff[2];
|
||||||
|
|
||||||
// Depending on wiring, the MCP41020 Digi-Pot may have the channel selection bits reversed. If so, we will need to...
|
|
||||||
// if (_ctrl == 0x01) _ctrl = 0x02 ; // Swap channel A/B bits
|
|
||||||
// else if (_ctrl == 0x02) _ctrl = 0x01 ; // Note: Do not change if both channels are selected (code = 0x03)
|
|
||||||
|
|
||||||
buff[0] = _ctrl | 0x10 ; // Set command bit to Write data
|
buff[0] = _ctrl | 0x10 ; // Set command bit to Write data
|
||||||
buff[1] = _data * 2.55 ; // Scale data byte (100%->255)
|
buff[1] = _data * 2.55 ; // Scale data byte (100%->255)
|
||||||
cs_select(Level_CS) ; // Transmit data to Digi-Pot
|
cs_select(Level_CS) ; // Transmit data to Digi-Pot
|
||||||
|
@ -659,7 +627,7 @@ static void getLine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SetVal(DAC DACobj[], int _Parm) {
|
int SetVal(DAC DACobj[], int _Parm) {
|
||||||
// Common code for setting frequency, duty cycle, phase, waaveform and level.
|
// Common code for setting frequency, duty cycle, phase, waveform and level.
|
||||||
// Handles options to set a specific value or bump up/down...
|
// Handles options to set a specific value or bump up/down...
|
||||||
if (inStr[3] == '+') { // Bump up and grab result for SPI display...
|
if (inStr[3] == '+') { // Bump up and grab result for SPI display...
|
||||||
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Bump(_Parm,_Up);
|
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Bump(_Parm,_Up);
|
||||||
|
@ -670,40 +638,53 @@ int SetVal(DAC DACobj[], int _Parm) {
|
||||||
} else { // Not a bump, so set the absolute value from Parm[0]...
|
} else { // Not a bump, so set the absolute value from Parm[0]...
|
||||||
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Set(_Parm,Parm[0]) ;
|
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Set(_Parm,Parm[0]) ;
|
||||||
if (SelectedChan & 0b10) result = DACobj[_DAC_B].Set(_Parm,Parm[0]) ;
|
if (SelectedChan & 0b10) result = DACobj[_DAC_B].Set(_Parm,Parm[0]) ;
|
||||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
|
||||||
}
|
}
|
||||||
|
// Disable the Ctrl channels...
|
||||||
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
// wait for Busy flag to clear...
|
||||||
|
|
||||||
|
// Abort the data channels...
|
||||||
|
dma_channel_abort(DACobj[_DAC_A].data_chan);
|
||||||
|
dma_channel_abort(DACobj[_DAC_B].data_chan);
|
||||||
|
|
||||||
|
// Reset the data transfer DMA's to the start of the data Bitmap...
|
||||||
|
dma_channel_set_read_addr(DACobj[_DAC_A].data_chan, &DACobj[_DAC_A].DAC_data[0], false);
|
||||||
|
dma_channel_set_read_addr(DACobj[_DAC_B].data_chan, &DACobj[_DAC_B].DAC_data[0], false);
|
||||||
|
|
||||||
|
// Re-enable the Ctrl channels (doesn't restart data transfer)...
|
||||||
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
|
||||||
|
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
||||||
return result ;
|
return result ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
bool InvX=false, InvY=false ; // Clock mode flags to allow inverted output
|
bool InvX=false, InvY=false ; // Clock display mode flags to allow inverted output
|
||||||
set_sys_clock_khz(SysClock*1000, true) ; // Set Pico clock speed
|
set_sys_clock_khz(SysClock*1000, true) ; // Set Pico clock speed
|
||||||
MaxDACfreq = clock_get_hz(clk_sys) / BitMapSize ; // Calculate Maximum DAC output frequency for given CPU clock speed
|
MaxDACfreq = clock_get_hz(clk_sys) / BitMapSize ; // Calculate Maximum DAC output frequency for given CPU clock speed
|
||||||
stdio_init_all() ;
|
stdio_init_all() ;
|
||||||
spi_init(SPI_PORT, 500000); // Set SPI0 at 0.5MHz.
|
|
||||||
|
spi_init(SPI_PORT, 500000); // Set SPI0 at 0.5MHz...
|
||||||
gpio_set_function(PIN_CLK, GPIO_FUNC_SPI);
|
gpio_set_function(PIN_CLK, GPIO_FUNC_SPI);
|
||||||
gpio_set_function(PIN_TX, GPIO_FUNC_SPI);
|
gpio_set_function(PIN_TX, GPIO_FUNC_SPI);
|
||||||
|
|
||||||
// Chip select is active-low, so initialise to a driven-high state...
|
gpio_init(Display_CS) ; // Initailse the required GPIO ports...
|
||||||
gpio_init(Display_CS);
|
|
||||||
gpio_set_dir(Display_CS, GPIO_OUT) ;
|
gpio_set_dir(Display_CS, GPIO_OUT) ;
|
||||||
gpio_put(Display_CS, 1);
|
gpio_put(Display_CS, 1) ; // Chip select is active-low, so initialise to high state
|
||||||
gpio_init(Level_CS) ;
|
gpio_init(Level_CS) ;
|
||||||
gpio_set_dir(Level_CS, GPIO_OUT) ;
|
gpio_set_dir(Level_CS, GPIO_OUT) ;
|
||||||
gpio_put(Level_CS, 1);
|
gpio_put(Level_CS, 1) ; // Chip select is active-low, so initialise to high state
|
||||||
|
gpio_init(PICO_DEFAULT_LED_PIN) ;
|
||||||
// Setting Max slew rate and gpio drive strength keeps output linear at high frequencies...
|
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT) ;
|
||||||
for (int i=0; i<16; i++) {
|
gpio_set_dir(PIN_CLK, GPIO_OUT) ; // Initialise remaining SPI connections...
|
||||||
gpio_set_slew_rate(i, GPIO_SLEW_RATE_FAST);
|
|
||||||
gpio_set_drive_strength(i, GPIO_DRIVE_STRENGTH_12MA);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialise remaining SPI connections...
|
|
||||||
gpio_set_dir(PIN_CLK, GPIO_OUT);
|
|
||||||
gpio_set_dir(PIN_TX, GPIO_OUT) ;
|
gpio_set_dir(PIN_TX, GPIO_OUT) ;
|
||||||
|
|
||||||
struct repeating_timer timer;
|
for (int i=0; i<16; i++) {
|
||||||
add_repeating_timer_ms(-1000, Repeating_Timer_Callback, NULL, &timer); // 7ms - Short enough to prevent Nixie tube flicker
|
gpio_set_slew_rate(i, GPIO_SLEW_RATE_FAST); // Setting Max slew rate and gpio drive strength keeps output
|
||||||
|
gpio_set_drive_strength(i, GPIO_DRIVE_STRENGTH_12MA); // linear at high frequencies...
|
||||||
|
}
|
||||||
|
|
||||||
memset(MarginFW,' ',MWidth) ; // Initialise Fixed Width margin...
|
memset(MarginFW,' ',MWidth) ; // Initialise Fixed Width margin...
|
||||||
MarginFW[MWidth] = '\0' ; // ... and terminate
|
MarginFW[MWidth] = '\0' ; // ... and terminate
|
||||||
|
@ -717,18 +698,14 @@ int main() {
|
||||||
DAC DACobj[2]; // Array to hold the two DAC channel objects
|
DAC DACobj[2]; // Array to hold the two DAC channel objects
|
||||||
DACobj[_DAC_A].DAC_chan('A',pio1,0); // First DAC channel object in array - resistor network connected to GPIO0->8
|
DACobj[_DAC_A].DAC_chan('A',pio1,0); // First DAC channel object in array - resistor network connected to GPIO0->8
|
||||||
DACobj[_DAC_B].DAC_chan('B',pio1,8); // Second DAC channel object in array - resistor network connected to GPIO8->16
|
DACobj[_DAC_B].DAC_chan('B',pio1,8); // Second DAC channel object in array - resistor network connected to GPIO8->16
|
||||||
blink_forever LED_blinky(pio0); // Onboard LED blinky object
|
|
||||||
|
|
||||||
strcpy(LastCmd,"?") ; // Hitting return will give 'Help'
|
strcpy(LastCmd,"?") ; // Hitting return will give 'Help'
|
||||||
|
|
||||||
SPI_Display_Write(SysClock) ; // Pico system clock speed (in MHz)
|
SPI_Display_Write(SysClock) ; // Pico system clock speed (in MHz)
|
||||||
MCP41020_Write(0x3, 50) ; // Both channels -> 50% output level
|
MCP41020_Write(0x3, 50) ; // Both channels -> 50% output level
|
||||||
|
|
||||||
LED_blinky.Set_Frequency(1); // Flash LED at 1Hz- waiting for USB connection
|
|
||||||
|
|
||||||
while (!stdio_usb_connected()) { sleep_ms(100); } // Wait for USB connection...
|
while (!stdio_usb_connected()) { sleep_ms(100); } // Wait for USB connection...
|
||||||
|
|
||||||
LED_blinky.Set_Frequency(10); // Flash LED at 10Hz - USB connected.
|
|
||||||
SPI_Display_Write(DACobj[_DAC_A].Freq) ; // Frequency => SPI display
|
SPI_Display_Write(DACobj[_DAC_A].Freq) ; // Frequency => SPI display
|
||||||
|
|
||||||
// Send (optional) start-up messages to terminal...
|
// Send (optional) start-up messages to terminal...
|
||||||
|
@ -736,7 +713,10 @@ int main() {
|
||||||
printf(ResultStr) ; // Update terminal
|
printf(ResultStr) ; // Update terminal
|
||||||
|
|
||||||
// Atomic Restart - starting all 4 DMA channels simultaneously ensures phase sync between both DAC channels
|
// Atomic Restart - starting all 4 DMA channels simultaneously ensures phase sync between both DAC channels
|
||||||
dma_start_channel_mask(DAC_channel_mask);
|
dma_start_channel_mask(DAC_channel_mask); // Sets the 'Busy' flag in Ctrl reg
|
||||||
|
|
||||||
|
struct repeating_timer timer;
|
||||||
|
add_repeating_timer_ms(-200, Repeating_Timer_Callback, NULL, &timer) ; // 5 x per second to blink LED
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
ParmCnt=0, Parm[0]=0, Parm[1]=0, Parm[2]=0, Parm[3]=0 ; // Reset all command line parameters
|
ParmCnt=0, Parm[0]=0, Parm[1]=0, Parm[2]=0, Parm[3]=0 ; // Reset all command line parameters
|
||||||
|
@ -760,7 +740,7 @@ int main() {
|
||||||
DACobj[_DAC_A].StatusString() ;
|
DACobj[_DAC_A].StatusString() ;
|
||||||
DACobj[_DAC_B].StatusString() ;
|
DACobj[_DAC_B].StatusString() ;
|
||||||
}
|
}
|
||||||
if (inStr[0] == 'I') SysInfo(DACobj, LED_blinky); // TBD - inconsitant - make these global ??
|
if (inStr[0] == 'I') SysInfo(DACobj); // TBD - inconsitant - make these global ??
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all remaining commands, the first character selects DAC channel A or B...
|
// For all remaining commands, the first character selects DAC channel A or B...
|
||||||
|
@ -800,10 +780,7 @@ int main() {
|
||||||
if ((inStr[1]=='p')&(inStr[2]=='h')) SetVal(DACobj,_Phase_) ; // Phase
|
if ((inStr[1]=='p')&(inStr[2]=='h')) SetVal(DACobj,_Phase_) ; // Phase
|
||||||
if ((inStr[1]=='l')&(inStr[2]=='e')) SetVal(DACobj,_Level_) ; // Level
|
if ((inStr[1]=='l')&(inStr[2]=='e')) SetVal(DACobj,_Level_) ; // Level
|
||||||
if ((inStr[1]=='s')&(inStr[2]=='i')) SetVal(DACobj,_Sine_) ; // Sine wave (optional harmonic parameter)
|
if ((inStr[1]=='s')&(inStr[2]=='i')) SetVal(DACobj,_Sine_) ; // Sine wave (optional harmonic parameter)
|
||||||
if ((inStr[1]=='f')&(inStr[2]=='r')) { // Frequency
|
if ((inStr[1]=='f')&(inStr[2]=='r')) SetVal(DACobj,_Freq_) ; // Frequency
|
||||||
SetVal(DACobj,_Freq_) ; // Set value
|
|
||||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
|
||||||
}
|
|
||||||
|
|
||||||
// The next two commands need different default values...
|
// The next two commands need different default values...
|
||||||
if (strlen(inStr)==3) Parm[0] = 50 ; // If no value provided, set default to 50
|
if (strlen(inStr)==3) Parm[0] = 50 ; // If no value provided, set default to 50
|
||||||
|
@ -811,43 +788,50 @@ int main() {
|
||||||
if ((inStr[1]=='t')&(inStr[2]=='r')) SetVal(DACobj,_Triangle_) ; // Set Triangle wave (optional duty cycle parameter)
|
if ((inStr[1]=='t')&(inStr[2]=='r')) SetVal(DACobj,_Triangle_) ; // Set Triangle wave (optional duty cycle parameter)
|
||||||
|
|
||||||
if ((inStr[1]=='t')&(inStr[2]=='i')) { // Time display...
|
if ((inStr[1]=='t')&(inStr[2]=='i')) { // Time display...
|
||||||
DACobj[_DAC_A].Set(_Phase_, 0) ; // Phase lock
|
// Disable the Ctrl channels...
|
||||||
DACobj[_DAC_B].Set(_Phase_, 0) ;
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
// wait for Busy flag to clear...
|
||||||
|
|
||||||
for (int gpio = 0; gpio < 16; gpio++) { // Grabs the GPIO back from the State machines
|
// Abort the data channels...
|
||||||
gpio_init(gpio);
|
dma_channel_abort(DACobj[_DAC_A].data_chan);
|
||||||
gpio_set_dir(gpio, GPIO_OUT);
|
dma_channel_abort(DACobj[_DAC_B].data_chan);
|
||||||
}
|
|
||||||
|
|
||||||
// Disable both DMA channels associated with this DAC...
|
// Re-enable the Ctrl channels (doesn't restart data transfer)...
|
||||||
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_A].data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_B].data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
// Reset the data transfer DMA's to the start of the data Bitmap...
|
|
||||||
dma_channel_set_read_addr(DACobj[_DAC_A].data_chan, &DACobj[_DAC_A].DAC_data[0], false);
|
|
||||||
dma_channel_set_read_addr(DACobj[_DAC_B].data_chan, &DACobj[_DAC_B].DAC_data[0], false);
|
|
||||||
|
|
||||||
pio_sm_set_enabled(pio1,0,false) ; // disable State machine 0 !! HARD CODED !!
|
pio_sm_set_enabled(pio1,0,false) ; // disable State machine 0 !! HARD CODED !!
|
||||||
pio_sm_set_enabled(pio1,1,false) ; // disable State machine 1
|
pio_sm_set_enabled(pio1,1,false) ; // disable State machine 1
|
||||||
|
|
||||||
|
for (uint i=0; i<16; i++) { // Grab the GPIO back from the State machines
|
||||||
|
gpio_init(i);
|
||||||
|
gpio_set_dir(i, GPIO_OUT);
|
||||||
|
}
|
||||||
gpio_clr_mask(0xff) ; // clear first 16 GPIO outputs
|
gpio_clr_mask(0xff) ; // clear first 16 GPIO outputs
|
||||||
|
|
||||||
ResultStr[0] = '\0' ; // String also used as a flag, so needs to be cleared
|
ResultStr[0] = '\0' ; // String also used as a flag, so needs to be cleared
|
||||||
while (ResultStr[0] == '\0') { // exit on keypress
|
while (ResultStr[0] == '\0') { // exit on keypress
|
||||||
float Radians ;
|
float Radians ;
|
||||||
|
int outX, outY ;
|
||||||
// Draw the clock face...
|
// Draw the clock face...
|
||||||
for (int i=0; i<sizeof(FaceX); i++) {
|
for (int i=0; i<sizeof(FaceX); i++) {
|
||||||
if (InvX) { gpio_put_masked(0x00ff,FaceX[i]) ; } // Write inverted data byte to DAC A
|
outX=FaceX[i] * DACobj[_DAC_A].Level / 100 ; // Scale output to match state machine settings
|
||||||
else { gpio_put_masked(0x00ff,255-FaceX[i]) ; } // Write non-inverted data byte to DAC A
|
outY=FaceY[i] * DACobj[_DAC_B].Level / 100 ;
|
||||||
if (InvY) { gpio_put_masked(0xff00,FaceY[i]<<8) ; } // Write inverted data byte to DAC B
|
if (InvX) { gpio_put_masked(0x00ff,outX) ; } // Write inverted data byte to DAC A
|
||||||
else { gpio_put_masked(0xff00,255-FaceY[i]<<8) ; } // Write non-inverted data byte to DAC B
|
else { gpio_put_masked(0x00ff,255-outX) ; } // Write non-inverted data byte to DAC A
|
||||||
|
if (InvY) { gpio_put_masked(0xff00,outY<<8) ; } // Write inverted data byte to DAC B
|
||||||
|
else { gpio_put_masked(0xff00,255-outY<<8) ; } // Write non-inverted data byte to DAC B
|
||||||
sleep_us(2) ; // Pause for on-screen persistance
|
sleep_us(2) ; // Pause for on-screen persistance
|
||||||
}
|
}
|
||||||
// Draw the clock hands...
|
// Draw the clock hands...
|
||||||
for (i=0; i<192; i++) { // 3 hands @ 64 pixels each = 192
|
for (i=0; i<192; i++) { // 3 hands @ 64 pixels each = 192
|
||||||
if (InvX) { gpio_put_masked(0x00ff,HandsX[i]) ; } // Write inverted data byte to DAC A
|
outX=HandsX[i] * DACobj[_DAC_A].Level / 100 ; // Scale output to match state machine settings
|
||||||
else { gpio_put_masked(0x00ff,255-HandsX[i]) ; } // Write non-inverted data byte to DAC A
|
outY=HandsY[i] * DACobj[_DAC_B].Level / 100 ;
|
||||||
if (InvY) { gpio_put_masked(0xff00,HandsY[i]<<8) ; } // Write inverted data byte to DAC B
|
if (InvX) { gpio_put_masked(0x00ff,outX) ; } // Write inverted data byte to DAC A
|
||||||
else { gpio_put_masked(0xff00,255-HandsY[i]<<8) ; } // Write non-inverted data byte to DAC B
|
else { gpio_put_masked(0x00ff,255-outX) ; } // Write non-inverted data byte to DAC A
|
||||||
|
if (InvY) { gpio_put_masked(0xff00,outY<<8) ; } // Write inverted data byte to DAC B
|
||||||
|
else { gpio_put_masked(0xff00,255-outY<<8) ; } // Write non-inverted data byte to DAC B
|
||||||
sleep_us(2) ; // Pause for on-screen persistance
|
sleep_us(2) ; // Pause for on-screen persistance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,17 +862,21 @@ int main() {
|
||||||
}
|
}
|
||||||
inStr[0]='\0' ; // Reset input buffer
|
inStr[0]='\0' ; // Reset input buffer
|
||||||
Hours=Parm[0]%24 ; Mins=Parm[1]%60 ; Secs=Parm[2]%60 ; // Set the time from parameters
|
Hours=Parm[0]%24 ; Mins=Parm[1]%60 ; Secs=Parm[2]%60 ; // Set the time from parameters
|
||||||
|
LEDCtr=0 ; // Force update and do it now
|
||||||
|
Repeating_Timer_Callback(&timer) ;
|
||||||
printf("\n%sClock set to %02d:%02d:%02d\n>",MarginFW,Hours,Mins,Secs) ;
|
printf("\n%sClock set to %02d:%02d:%02d\n>",MarginFW,Hours,Mins,Secs) ;
|
||||||
}
|
}
|
||||||
else if ((c=='q') or (c=='Q')) {
|
else if ((c=='q') or (c=='Q')) {
|
||||||
strcpy(ResultStr," Quit clock mode\n") ; // Prevents error message
|
for (uint i=0; i<16; i++) { pio_gpio_init(pio1, i); } // Hand the GPIO's back to the state machines
|
||||||
// Re-enable both DMA channels associated with this DAC...
|
|
||||||
hw_set_bits(&dma_hw->ch[DACobj[_DAC_A].data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
// Reset the data transfer DMA's to the start of the data Bitmap...
|
||||||
hw_set_bits(&dma_hw->ch[DACobj[_DAC_B].data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
dma_channel_set_read_addr(DACobj[_DAC_A].data_chan, &DACobj[_DAC_A].DAC_data[0], false);
|
||||||
|
dma_channel_set_read_addr(DACobj[_DAC_B].data_chan, &DACobj[_DAC_B].DAC_data[0], false);
|
||||||
pio_sm_set_enabled(pio1,0,true) ; // Re-enable State machine 0 !! HARD CODED !!
|
pio_sm_set_enabled(pio1,0,true) ; // Re-enable State machine 0 !! HARD CODED !!
|
||||||
pio_sm_set_enabled(pio1,1,true) ; // Re-enable State machine 1
|
pio_sm_set_enabled(pio1,1,true) ; // Re-enable State machine 1
|
||||||
// Re-init the state machines ????
|
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
||||||
|
|
||||||
|
strcpy(ResultStr," Quit clock mode\n") ; // Prevents error message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,6 +897,19 @@ int main() {
|
||||||
sleep_ms(Parm[3]); }
|
sleep_ms(Parm[3]); }
|
||||||
if (i>=Parm[1]) { dirn =-1;
|
if (i>=Parm[1]) { dirn =-1;
|
||||||
sleep_ms(Parm[3]); }
|
sleep_ms(Parm[3]); }
|
||||||
|
// Disable the Ctrl channels...
|
||||||
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
// wait for Busy flag to clear...
|
||||||
|
|
||||||
|
// Abort the data channels...
|
||||||
|
dma_channel_abort(DACobj[_DAC_A].data_chan);
|
||||||
|
dma_channel_abort(DACobj[_DAC_B].data_chan);
|
||||||
|
|
||||||
|
// Re-enable the Ctrl channels (doesn't restart data transfer)...
|
||||||
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_A].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
hw_set_bits(&dma_hw->ch[DACobj[_DAC_B].ctrl_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||||
|
|
||||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
||||||
i = i + dirn;
|
i = i + dirn;
|
||||||
c = getchar_timeout_us (0); // Non-blocking char input
|
c = getchar_timeout_us (0); // Non-blocking char input
|
||||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -1,35 +0,0 @@
|
||||||
.program pio_blink
|
|
||||||
; Turn on LED for 1002 cycles and off for 1002 cycles.
|
|
||||||
; Large delays are required to allow the State Machine to toggle at frequencies as low as 1Hz.
|
|
||||||
; Note: Oscilloscope shows this runs about 2% fast indicating an issue with the cycle count.
|
|
||||||
.wrap_target
|
|
||||||
set pins, 1 ; Turn LED on
|
|
||||||
set x,25
|
|
||||||
; 2 cycles to this point
|
|
||||||
label01:
|
|
||||||
nop [19] ; 20 cycles
|
|
||||||
nop [18] ; 19 cycles
|
|
||||||
jmp x--, label01 ; 1 cycles
|
|
||||||
; ; 2 + 25*(20+19+1) = 1002 cycles to this point
|
|
||||||
; (restart cycle count)
|
|
||||||
set pins, 0 ; Turn LED off
|
|
||||||
set x,25
|
|
||||||
; 2 cycles to this point
|
|
||||||
label02:
|
|
||||||
nop [19] ; 20 cycles
|
|
||||||
nop [18] ; 19 cycles
|
|
||||||
jmp x--, label02 ; 1 cycles
|
|
||||||
; ; 2 + 25*(20+19+1) = 1002 cycles to this point
|
|
||||||
.wrap ; Blink forever!
|
|
||||||
|
|
||||||
% c-sdk {
|
|
||||||
// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin
|
|
||||||
|
|
||||||
void blink_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
|
||||||
pio_gpio_init(pio, pin);
|
|
||||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
|
|
||||||
pio_sm_config c = pio_blink_program_get_default_config(offset);
|
|
||||||
sm_config_set_set_pins(&c, pin, 1);
|
|
||||||
pio_sm_init(pio, sm, offset, &c);
|
|
||||||
}
|
|
||||||
%}
|
|
Ładowanie…
Reference in New Issue