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
|
||||
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_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_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 <string.h>
|
||||
#include <ctype.h>
|
||||
|
@ -9,7 +13,6 @@
|
|||
#include "hardware/dma.h"
|
||||
#include "blink.pio.h"
|
||||
#include "DAC.pio.h"
|
||||
|
||||
#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 280 // Overclock for 1.000 MHz DAC output
|
||||
|
||||
// Data for clock face generated by 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,
|
||||
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} ;
|
||||
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,
|
||||
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} ;
|
||||
// (Number of pixels: 421)
|
||||
// Data for the clock face is generated externally using an Excel spreadsheet...
|
||||
uint8_t FaceX[] = {
|
||||
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,
|
||||
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,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,
|
||||
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...
|
||||
uint8_t HandsX[192] = {} ; // Each hand requires 64 bytes - 3x64=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 ;
|
||||
|
||||
int tmp ;
|
||||
|
@ -129,32 +140,14 @@ public:
|
|||
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) {
|
||||
switch (_type) {
|
||||
case _Freq_:
|
||||
Freq = _val ; // Frequency (numeric)
|
||||
ReInit() ; // Stop and reset the DAC channel (no restart)
|
||||
DACspeed(Freq * Range) ; // Update State machine run speed
|
||||
break ;
|
||||
case _Phase_:
|
||||
Phase = _val ; // Phase shift (0->355 degrees)
|
||||
ReInit() ; // Stop and reset the DAC channel (no restart)
|
||||
DataCalc() ; // Recalc Bitmap and apply new phase value
|
||||
break ;
|
||||
case _Level_:
|
||||
|
@ -194,7 +187,7 @@ public:
|
|||
strcpy(ResultStr,MarginVW) ;
|
||||
strcat(ResultStr,"Error - Minimum Frequency\n") ;
|
||||
}
|
||||
// TBD - remove hardcoded Max frequency
|
||||
// TBD - remove hardcoded Max frequency
|
||||
else if ((Freq*Range==1000000) && (_dirn==_Up)) { // Attempt to bump above upper limit
|
||||
// else if ((Freq*Range>=MaxDACfreq) && (_dirn==_Up)) { // Attempt to bump above upper limit
|
||||
MarginVW[MWidth - MarginCount] = '\0' ; // Calculate padding required for command characters and cursor
|
||||
|
@ -260,9 +253,9 @@ public:
|
|||
if (_frequency >= 34) { // Fast DAC ( Frequency range from 34Hz to 999Khz )
|
||||
SM_WrapTop = SM_WrapBot ; // SM program memory = 1 op-code
|
||||
pio_sm_set_wrap (pio, StateMachine, SM_WrapBot, SM_WrapTop) ; // Fast loop (1 clock cycle)
|
||||
// If the previous frequency was < 33Hz, we will have just shrunk the assembler from 4 op-codes down to 1.
|
||||
// This leaves the State Machine program counter pointing outside of the new WRAP statement, which crashes the SM.
|
||||
// To avoid this, we need to also reset the State Machine program counter...
|
||||
// If the previous frequency was < 33Hz, we will have just shrunk the assembler from 4 op-codes down to 1.
|
||||
// This leaves the State Machine program counter pointing outside of the new WRAP statement, which crashes the SM.
|
||||
// To avoid this, we need to also reset the State Machine program counter...
|
||||
pio->sm[StateMachine].instr = SM_WrapBot ; // Reset State Machine PC to start of code
|
||||
pio_sm_set_clkdiv(pio, StateMachine, DAC_div); // Set the State Machine clock
|
||||
} else { // Slow DAC ( 1Hz=>33Hz )
|
||||
|
@ -270,8 +263,8 @@ public:
|
|||
DAC_freq = DAC_freq * 64;
|
||||
SM_WrapTop = SM_WrapBot + 3 ; // SM program memory = 4 op-codes
|
||||
pio_sm_set_wrap (pio, StateMachine, SM_WrapBot, SM_WrapTop) ; // slow loop (64 clock cycles)
|
||||
// If the previous frequency was >= 34Hz, we will have just expanded the assembler code from 1 op-code up to 4.
|
||||
// The State Machine program counter will still be pointing to an op-code within the new WRAP statement, so will not crash.
|
||||
// If the previous frequency was >= 34Hz, we will have just expanded the assembler code from 1 op-code up to 4.
|
||||
// The State Machine program counter will still be pointing to an op-code within the new WRAP statement, so will not crash.
|
||||
pio_sm_set_clkdiv(pio, StateMachine, DAC_div); // Set the State Machine clock speed
|
||||
}
|
||||
StatusString () ; // Update the terminal session
|
||||
|
@ -282,7 +275,7 @@ public:
|
|||
int _phase;
|
||||
float a,b,x1,x2,g1,g2;
|
||||
|
||||
// Scale the phase shift to match data size...
|
||||
// Scale the phase shift to match data size...
|
||||
_phase = Phase * BitMapSize / 360 ; // Input range: 0 -> 360 (degrees)
|
||||
// Output range: 0 -> 255 (bytes)
|
||||
switch (Funct) {
|
||||
|
@ -398,69 +391,58 @@ 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) {
|
||||
// Routine called 5 times per second...
|
||||
int i, steps=64, MidX=128, MidY=128 ;
|
||||
// Bump the time...
|
||||
if ((++Secs)>59) Secs=0 ; // Always bump seconds
|
||||
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
|
||||
// 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
|
||||
|
||||
// Calculate seconds hand...
|
||||
i=0, Radius=127 ; // Radius=Length of seconds hand
|
||||
Angle=270-(Secs*6) ; // Angle in degrees, shifted 90 degree anti-clockwise
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
while(i<steps) { HandsX[i]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
// Calculate minutes hand...
|
||||
i=0, Radius=95 ; // Radius=Length of minutes hand
|
||||
Angle=270-(Mins*6) ; // Angle in degrees, shifted 90 degree anti-clockwise
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
i=0 ;
|
||||
while(i<steps) { HandsX[i+steps]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i+steps]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
// Calculate 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.
|
||||
// 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,
|
||||
// and scaled by 5 to provide range 0=>12
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
while(i<steps) { HandsX[i+2*steps]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i+2*steps]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
// Bump the clock...
|
||||
if ((++Secs)>59) Secs=0 ; // Always bump seconds
|
||||
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
|
||||
|
||||
// printf("%s%d:%d:%d - %d\n",MarginFW,Hours,Mins,Secs,tmp) ; // Debug
|
||||
// Calculate seconds hand...
|
||||
i=0, Radius=127 ; // Radius=Length of seconds hand
|
||||
Angle=270-(Secs*6) ; // Angle in degrees, shifted 90 degree anti-clockwise
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
while(i<steps) { HandsX[i]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
// Calculate minutes hand...
|
||||
i=0, Radius=95 ; // Radius=Length of minutes hand
|
||||
Angle=270-(Mins*6) ; // Angle in degrees, shifted 90 degree anti-clockwise
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
i=0 ;
|
||||
while(i<steps) { HandsX[i+steps]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i+steps]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
// Calculate hours hand...
|
||||
i=0, Radius=64 ; // Radius=Length of hours hand
|
||||
// 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.
|
||||
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
|
||||
Radians=Angle*3.14159/180 ; // Angle in radians
|
||||
StartX=Radius*cos(Radians)+MidX ;
|
||||
StartY=Radius*sin(Radians)+MidY ;
|
||||
while(i<steps) { HandsX[i+2*steps]=StartX+i*(MidX-StartX)/steps ;
|
||||
HandsY[i+2*steps]=StartY+i*(MidY-StartY)/steps ;
|
||||
i++ ; }
|
||||
|
||||
// printf("%s%d:%d:%d - %d\n",MarginFW,Hours,Mins,Secs,tmp) ; // Debug
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -469,11 +451,11 @@ void VerText () {
|
|||
tmp = strlen(inStr) ; // Get number of command line characters
|
||||
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
|
||||
sprintf(ResultStr, "%s|--------------------|\n"
|
||||
"%s| Function Generator |\n"
|
||||
"%s| Version 1.0.0 |\n"
|
||||
"%s| 11th August 2023 |\n"
|
||||
"%s|--------------------|\n",
|
||||
sprintf(ResultStr, "%s|---------------------|\n"
|
||||
"%s| Function Generator |\n"
|
||||
"%s| Version 1.0.0 |\n"
|
||||
"%s| 19th September 2023 |\n"
|
||||
"%s|---------------------|\n",
|
||||
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>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"
|
||||
"%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",
|
||||
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 ) ;
|
||||
}
|
||||
|
||||
void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
||||
void SysInfo (DAC DACobj[] ) {
|
||||
// Print System Info and resource allocation detils, aligned to current margin settings...
|
||||
// Note: 1) The following string requires '%%%%' to print '%' because...
|
||||
// a) ResultStr is copied to outStr using sprintf - this reduces '%%%%' to '%%'
|
||||
|
@ -534,15 +518,9 @@ void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
|||
sprintf(ResultStr,"%s|----------------------------------------------------------|\n"
|
||||
"%s| System Info... |\n"
|
||||
"%s|----------------------------------------------------------|\n"
|
||||
"%s| Target board: Pico |\n"
|
||||
"%s| RP2040 clock frequency: %7.3fMHz |\n"
|
||||
"%s| Max DAC frequency: %7.3fMHz |\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| Max DAC frequency: %7.3fMHz |\n"
|
||||
"%s|----------------------------|-----------------------------|\n"
|
||||
"%s| DAC Channel A | DAC Channel B |\n"
|
||||
"%s|----------------------------|-----------------------------|\n"
|
||||
|
@ -553,14 +531,9 @@ void SysInfo (DAC DACobj[], blink_forever LED_blinky) {
|
|||
"%s| Duty cycle: %3d%%%% | Duty cycle: %3d%%%% |\n"
|
||||
"%s| Sine harmonic: %1d | Sine harmonic: %1d |\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, MaxDACfreq/1000000,
|
||||
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].Freq, DACobj[_DAC_B].Freq,
|
||||
|
@ -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.
|
||||
// Transmit data over the SPI bus to the Digi-Pot.
|
||||
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[1] = _data * 2.55 ; // Scale data byte (100%->255)
|
||||
cs_select(Level_CS) ; // Transmit data to Digi-Pot
|
||||
|
@ -659,8 +627,8 @@ static void getLine() {
|
|||
}
|
||||
|
||||
int SetVal(DAC DACobj[], int _Parm) {
|
||||
// Common code for setting frequency, duty cycle, phase, waaveform and level.
|
||||
// Handles options to set a specific value or bump up/down...
|
||||
// Common code for setting frequency, duty cycle, phase, waveform and level.
|
||||
// Handles options to set a specific value or bump up/down...
|
||||
if (inStr[3] == '+') { // Bump up and grab result for SPI display...
|
||||
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Bump(_Parm,_Up);
|
||||
if (SelectedChan & 0b10) result = DACobj[_DAC_B].Bump(_Parm,_Up) ;
|
||||
|
@ -670,73 +638,85 @@ int SetVal(DAC DACobj[], int _Parm) {
|
|||
} 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 & 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 ;
|
||||
}
|
||||
|
||||
int main() {
|
||||
bool InvX=false, InvY=false ; // Clock mode flags to allow inverted output
|
||||
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
|
||||
int main() {
|
||||
bool InvX=false, InvY=false ; // Clock display mode flags to allow inverted output
|
||||
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
|
||||
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_TX, GPIO_FUNC_SPI);
|
||||
|
||||
// Chip select is active-low, so initialise to a driven-high state...
|
||||
gpio_init(Display_CS);
|
||||
gpio_set_dir(Display_CS, GPIO_OUT);
|
||||
gpio_put(Display_CS, 1);
|
||||
gpio_init(Level_CS);
|
||||
gpio_set_dir(Level_CS, GPIO_OUT);
|
||||
gpio_put(Level_CS, 1);
|
||||
gpio_init(Display_CS) ; // Initailse the required GPIO ports...
|
||||
gpio_set_dir(Display_CS, GPIO_OUT) ;
|
||||
gpio_put(Display_CS, 1) ; // Chip select is active-low, so initialise to high state
|
||||
gpio_init(Level_CS) ;
|
||||
gpio_set_dir(Level_CS, GPIO_OUT) ;
|
||||
gpio_put(Level_CS, 1) ; // Chip select is active-low, so initialise to high state
|
||||
gpio_init(PICO_DEFAULT_LED_PIN) ;
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT) ;
|
||||
gpio_set_dir(PIN_CLK, GPIO_OUT) ; // Initialise remaining SPI connections...
|
||||
gpio_set_dir(PIN_TX, GPIO_OUT) ;
|
||||
|
||||
// Setting Max slew rate and gpio drive strength keeps output linear at high frequencies...
|
||||
for (int i=0; i<16; i++) {
|
||||
gpio_set_slew_rate(i, GPIO_SLEW_RATE_FAST);
|
||||
gpio_set_drive_strength(i, GPIO_DRIVE_STRENGTH_12MA);
|
||||
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...
|
||||
}
|
||||
|
||||
// Initialise remaining SPI connections...
|
||||
gpio_set_dir(PIN_CLK, GPIO_OUT);
|
||||
gpio_set_dir(PIN_TX, GPIO_OUT);
|
||||
|
||||
struct repeating_timer timer;
|
||||
add_repeating_timer_ms(-1000, Repeating_Timer_Callback, NULL, &timer); // 7ms - Short enough to prevent Nixie tube flicker
|
||||
|
||||
memset(MarginFW,' ',MWidth) ; // Initialise Fixed Width margin...
|
||||
MarginFW[MWidth] = '\0' ; // ... and terminate
|
||||
memset(MarginVW,' ',MWidth) ; // Initialise Variable Width margin...
|
||||
MarginVW[MWidth] = '\0' ; // ... and terminate
|
||||
ResultStr[0] = '\0' ; // Reset string
|
||||
|
||||
// Instantiate objects to control the various State Machines...
|
||||
// Note: Both DAC channels need to be on the same PIO to achieve
|
||||
// Atomic restarts for accurate phase sync.
|
||||
// Instantiate objects to control the various State Machines...
|
||||
// Note: Both DAC channels need to be on the same PIO to achieve
|
||||
// Atomic restarts for accurate phase sync.
|
||||
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_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'
|
||||
|
||||
SPI_Display_Write(SysClock) ; // Pico system clock speed (in MHz)
|
||||
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...
|
||||
|
||||
LED_blinky.Set_Frequency(10); // Flash LED at 10Hz - USB connected.
|
||||
SPI_Display_Write(DACobj[_DAC_A].Freq) ; // Frequency => SPI display
|
||||
|
||||
// Send (optional) start-up messages to terminal...
|
||||
// Send (optional) start-up messages to terminal...
|
||||
VerText() ; // Version text
|
||||
printf(ResultStr) ; // Update terminal
|
||||
|
||||
// Atomic Restart - starting all 4 DMA channels simultaneously ensures phase sync between both DAC channels
|
||||
dma_start_channel_mask(DAC_channel_mask);
|
||||
// Atomic Restart - starting all 4 DMA channels simultaneously ensures phase sync between both DAC channels
|
||||
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) {
|
||||
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_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...
|
||||
|
@ -797,57 +777,61 @@ int main() {
|
|||
}
|
||||
|
||||
// Next two chars select the command...
|
||||
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]=='s')&(inStr[2]=='i')) SetVal(DACobj,_Sine_) ; // Sine wave (optional harmonic parameter)
|
||||
if ((inStr[1]=='f')&(inStr[2]=='r')) { // Frequency
|
||||
SetVal(DACobj,_Freq_) ; // Set value
|
||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart both DAC channels
|
||||
}
|
||||
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]=='s')&(inStr[2]=='i')) SetVal(DACobj,_Sine_) ; // Sine wave (optional harmonic parameter)
|
||||
if ((inStr[1]=='f')&(inStr[2]=='r')) SetVal(DACobj,_Freq_) ; // Frequency
|
||||
|
||||
// The next two commands need different default values...
|
||||
if (strlen(inStr)==3) Parm[0] = 50 ; // If no value provided, set default to 50
|
||||
if ((inStr[1]=='s')&(inStr[2]=='q')) SetVal(DACobj,_Square_) ; // Set Square wave (optional duty cycle parameter)
|
||||
if ((inStr[1]=='t')&(inStr[2]=='r')) SetVal(DACobj,_Triangle_) ; // Set Triangle wave (optional duty cycle parameter)
|
||||
if (strlen(inStr)==3) Parm[0] = 50 ; // If no value provided, set default to 50
|
||||
if ((inStr[1]=='s')&(inStr[2]=='q')) SetVal(DACobj,_Square_) ; // Set Square 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...
|
||||
DACobj[_DAC_A].Set(_Phase_, 0) ; // Phase lock
|
||||
DACobj[_DAC_B].Set(_Phase_, 0) ;
|
||||
if ((inStr[1]=='t')&(inStr[2]=='i')) { // Time display...
|
||||
// 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...
|
||||
|
||||
for (int gpio = 0; gpio < 16; gpio++) { // Grabs the GPIO back from the State machines
|
||||
gpio_init(gpio);
|
||||
gpio_set_dir(gpio, GPIO_OUT);
|
||||
}
|
||||
// Abort the data channels...
|
||||
dma_channel_abort(DACobj[_DAC_A].data_chan);
|
||||
dma_channel_abort(DACobj[_DAC_B].data_chan);
|
||||
|
||||
// Disable both DMA channels associated with this DAC...
|
||||
hw_clear_bits(&dma_hw->ch[DACobj[_DAC_A].data_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);
|
||||
// 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);
|
||||
|
||||
pio_sm_set_enabled(pio1,0,false) ; // disable State machine 0 !! HARD CODED !!
|
||||
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
|
||||
|
||||
ResultStr[0] = '\0' ; // String also used as a flag, so needs to be cleared
|
||||
while (ResultStr[0] == '\0') { // exit on keypress
|
||||
float Radians ;
|
||||
int outX, outY ;
|
||||
// Draw the clock face...
|
||||
for (int i=0; i<sizeof(FaceX); i++) {
|
||||
if (InvX) { gpio_put_masked(0x00ff,FaceX[i]) ; } // Write inverted data byte to DAC A
|
||||
else { gpio_put_masked(0x00ff,255-FaceX[i]) ; } // Write non-inverted data byte to DAC A
|
||||
if (InvY) { gpio_put_masked(0xff00,FaceY[i]<<8) ; } // Write inverted data byte to DAC B
|
||||
else { gpio_put_masked(0xff00,255-FaceY[i]<<8) ; } // Write non-inverted data byte to DAC B
|
||||
outX=FaceX[i] * DACobj[_DAC_A].Level / 100 ; // Scale output to match state machine settings
|
||||
outY=FaceY[i] * DACobj[_DAC_B].Level / 100 ;
|
||||
if (InvX) { gpio_put_masked(0x00ff,outX) ; } // Write inverted data byte to DAC A
|
||||
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
|
||||
}
|
||||
// Draw the clock hands...
|
||||
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
|
||||
else { gpio_put_masked(0x00ff,255-HandsX[i]) ; } // Write non-inverted data byte to DAC A
|
||||
if (InvY) { gpio_put_masked(0xff00,HandsY[i]<<8) ; } // Write inverted data byte to DAC B
|
||||
else { gpio_put_masked(0xff00,255-HandsY[i]<<8) ; } // Write non-inverted data byte to DAC B
|
||||
outX=HandsX[i] * DACobj[_DAC_A].Level / 100 ; // Scale output to match state machine settings
|
||||
outY=HandsY[i] * DACobj[_DAC_B].Level / 100 ;
|
||||
if (InvX) { gpio_put_masked(0x00ff,outX) ; } // Write inverted data byte to DAC A
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -878,17 +862,21 @@ int main() {
|
|||
}
|
||||
inStr[0]='\0' ; // Reset input buffer
|
||||
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) ;
|
||||
}
|
||||
else if ((c=='q') or (c=='Q')) {
|
||||
strcpy(ResultStr," Quit clock mode\n") ; // Prevents error message
|
||||
// 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);
|
||||
hw_set_bits(&dma_hw->ch[DACobj[_DAC_B].data_chan].al1_ctrl, DMA_CH0_CTRL_TRIG_EN_BITS);
|
||||
for (uint i=0; i<16; i++) { pio_gpio_init(pio1, i); } // Hand the GPIO's back to the state machines
|
||||
|
||||
// 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,true) ; // Re-enable State machine 0 !! HARD CODED !!
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -896,31 +884,44 @@ int main() {
|
|||
|
||||
// The final command is a continual loop creating the sweep function...
|
||||
if ((inStr[1] == 's') & (inStr[2] == 'w')) { // Sweep
|
||||
// Parm[0]=Low frequency, Parm[1]=High frequency, Parm[2]=Scan speed, Parm[3]=Low/High pause
|
||||
// Parm[0]=Low frequency, Parm[1]=High frequency, Parm[2]=Scan speed, Parm[3]=Low/High pause
|
||||
i = Parm[0];
|
||||
for (;;) {
|
||||
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Set(_Freq_,i) ; // Set frequency, display status
|
||||
if (SelectedChan & 0b10) result = DACobj[_DAC_B].Set(_Freq_,i) ; // Set frequency, display status
|
||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart all 4 DMA channels...
|
||||
printf(ResultStr) ; // Update terminal
|
||||
ResultStr[0] = '\0' ; // Reset the string variable
|
||||
SPI_Display_Write(i); // Update SPI display
|
||||
if (SelectedChan & 0b01) result = DACobj[_DAC_A].Set(_Freq_,i) ; // Set frequency, display status
|
||||
if (SelectedChan & 0b10) result = DACobj[_DAC_B].Set(_Freq_,i) ; // Set frequency, display status
|
||||
dma_start_channel_mask(DAC_channel_mask); // Atomic restart all 4 DMA channels...
|
||||
printf(ResultStr) ; // Update terminal
|
||||
ResultStr[0] = '\0' ; // Reset the string variable
|
||||
SPI_Display_Write(i); // Update SPI display
|
||||
if (i==Parm[0]) { dirn = 1;
|
||||
sleep_ms(Parm[3]); }
|
||||
if (i>=Parm[1]) { dirn =-1;
|
||||
sleep_ms(Parm[3]); }
|
||||
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);
|
||||
|
||||
// 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
|
||||
i = i + dirn;
|
||||
c = getchar_timeout_us (0); // Non-blocking char input
|
||||
c = getchar_timeout_us (0); // Non-blocking char input
|
||||
if ((c>=32) & (c<=126)) {
|
||||
strcpy(ResultStr," Exit sweep mode\n") ; // Prevents error message
|
||||
break; } // exit on keypress
|
||||
sleep_ms(Parm[2]); // Speed of scan
|
||||
strcpy(ResultStr," Exit sweep mode\n") ; // Prevents error message
|
||||
break; } // exit on keypress
|
||||
sleep_ms(Parm[2]); // Speed of scan
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(ResultStr) == 0) { // No result can only mean unrecognised command
|
||||
strcpy(MarginVW,MarginFW) ; // Reset Variable Width margin
|
||||
if (strlen(ResultStr) == 0) { // No result can only mean unrecognised command
|
||||
strcpy(MarginVW,MarginFW) ; // Reset Variable Width margin
|
||||
tmp = strlen(inStr) ;
|
||||
if (tmp != 0) tmp ++ ; // Bump to allow for cursor character
|
||||
MarginVW[MWidth - tmp] = '\0' ; // Calculate padding for input and cursor
|
||||
|
|
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