|
1 | 1 | #include "RP2350PIOCurrentSense.h" |
2 | 2 |
|
3 | | - RP2350PIOCurrentSense::RP2350PIOCurrentSense(float gain, uint32_t max_adc_value, int pinA, int pinB, int pinC) : CurrentSense() { |
4 | | - this->pinA = pinA; |
5 | | - this->pinB = pinB; |
6 | | - this->pinC = pinC; |
| 3 | + RP2350PIOCurrentSense::RP2350PIOCurrentSense(float gain, uint32_t max_adc_value, int pinSCK, int pinCSB, int pinD0) : CurrentSense() { |
| 4 | + this->pinSCK = pinSCK; |
| 5 | + this->pinCSB = pinCSB; |
| 6 | + this->pinD0 = pinD0; |
| 7 | + this->pinD1 = pinD0+1; |
| 8 | + this->pinD2 = pinD0+2; |
7 | 9 | this->gain_a = gain; |
8 | 10 | this->gain_b = gain; |
9 | 11 | this->gain_c = gain; |
10 | 12 | this->max_adc_value = max_adc_value; |
| 13 | + |
11 | 14 | }; |
12 | 15 |
|
13 | 16 |
|
|
19 | 22 | // TODO check that pins are valid for PIO use (e.g. consecutive pins on same bank) |
20 | 23 | // TODO check that driver is linked |
21 | 24 |
|
22 | | - // TODO init PIO |
| 25 | + // Done init PIO |
23 | 26 | // TODO init ADC via SPI |
24 | 27 | // TODO init DMA to transfer ADC data to memory buffer |
25 | 28 | // TODO init timer to trigger PIO conversions at required frequency (check driver settings) |
26 | 29 | // TDB: do we need config input to know which timer slice and channel to use? or can we pick automatically? |
27 | 30 | // TODO start everything up |
28 | 31 |
|
| 32 | + |
| 33 | + float sck_hz = 20e6; |
| 34 | + PIO pio = pio0; |
| 35 | + int sm = pio_claim_unused_sm(pio0, false); |
| 36 | + if (sm < 0) { pio = pio1; sm = pio_claim_unused_sm(pio1, true); } |
| 37 | + |
| 38 | + uint off = pio_add_program(pio, &bu79100g_parallel3_program); |
| 39 | + pio_sm_config c = bu79100g_parallel3_program_get_default_config(off); |
| 40 | + |
| 41 | + // Map pins to the SM |
| 42 | + sm_config_set_in_pins(&c, this->pinD0); // reads D0..D2 |
| 43 | + sm_config_set_set_pins(&c, this->pinCSB, 1); // CSB (1 pin) |
| 44 | + sm_config_set_sideset_pins(&c, this->pinSCK); // SCK (sideset) |
| 45 | + |
| 46 | + // Put pins into PIO control |
| 47 | + pio_gpio_init(pio, this->pinSCK); |
| 48 | + pio_gpio_init(pio, this->pinCSB); |
| 49 | + pio_gpio_init(pio, this->pinD0); |
| 50 | + pio_gpio_init(pio, this->pinD1); |
| 51 | + pio_gpio_init(pio, this->pinD2); |
| 52 | + |
| 53 | + // Directions (from the SM’s point of view) |
| 54 | + pio_sm_set_consecutive_pindirs(pio, sm, this->pinSCK, 1, true); // SCK out |
| 55 | + pio_sm_set_consecutive_pindirs(pio, sm, this->pinCSB, 1, true); // CS out |
| 56 | + pio_sm_set_consecutive_pindirs(pio, sm, this->pinD0, 3, false); // D0..D2 in |
| 57 | + |
| 58 | + // Shift config: right, autopush every 24 bits (two pushes per conversion) |
| 59 | + sm_config_set_in_shift(&c, true, true, 24); |
| 60 | + |
| 61 | + // SCK ≈ clk_sys / (2 * clkdiv) because each SCK period = 2 instructions |
| 62 | + float div = (float)clock_get_hz(clk_sys) / (2.0f * sck_hz); |
| 63 | + sm_config_set_clkdiv(&c, div); |
| 64 | + |
| 65 | + // Init & start the SM |
| 66 | + pio_sm_init(pio, sm, off, &c); |
| 67 | + pio_sm_set_enabled(pio, sm, true); |
| 68 | + |
29 | 69 | return 0; |
30 | 70 | }; |
31 | 71 |
|
|
0 commit comments