kopia lustrzana https://github.com/gnea/grbl
feat: spi fixes
rodzic
c7b5ea98fd
commit
6f55bd0446
168
grbl/mo_spi.c
168
grbl/mo_spi.c
|
|
@ -1,139 +1,99 @@
|
|||
|
||||
#include "grbl.h"
|
||||
#define CS1_PORT PORTC // Chip Select for Driver 1
|
||||
#define CS1_PIN PC0
|
||||
|
||||
#define CS2_PORT PORTC // Chip Select for Driver 2
|
||||
#define CS2_PIN PC1
|
||||
#define CS1_PIN PC0
|
||||
#define CS2_PIN PC1
|
||||
|
||||
void debug_print(const char *msg)
|
||||
{
|
||||
while (*msg)
|
||||
{
|
||||
serial_write(*msg++); // Send each character over serial
|
||||
}
|
||||
#define DEBUG_SPI
|
||||
|
||||
#ifdef DEBUG_SPI
|
||||
void debug_print_read(uint8_t addr, uint8_t data) {
|
||||
serial_write('R');
|
||||
serial_write('[');
|
||||
if (addr < 16) serial_write('0');
|
||||
serial_write((addr < 10) ? ('0' + addr) : ('A' + addr - 10));
|
||||
serial_write(']');
|
||||
serial_write('=');
|
||||
if (data < 16) serial_write('0');
|
||||
serial_write((data >> 4) < 10 ? ('0' + (data >> 4)) : ('A' + (data >> 4) - 10));
|
||||
serial_write((data & 0xF) < 10 ? ('0' + (data & 0xF)) : ('A' + (data & 0xF) - 10));
|
||||
serial_write('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
// Chip Select Pin Definitions
|
||||
#define CS1_PIN PC0 // Chip Select for Driver 1
|
||||
#define CS2_PIN PC1 // Chip Select for Driver 2
|
||||
|
||||
// SPI Timing Parameters (in ns)
|
||||
#define SPI_SCLK_PERIOD 100
|
||||
#define SPI_SETUP_TIME 20
|
||||
#define SPI_HOLD_TIME 30
|
||||
|
||||
// Function to initialize SPI communication
|
||||
void SPI_init() {
|
||||
// Set MOSI, SCK, and SS as output
|
||||
DDRB |= (1 << PB3) | (1 << PB5) | (1 << PB2);
|
||||
|
||||
// Set Chip Select pins as outputs
|
||||
DDRC |= (1 << CS1_PIN) | (1 << CS2_PIN);
|
||||
|
||||
// Deselect all chips
|
||||
PORTC |= (1 << CS1_PIN) | (1 << CS2_PIN);
|
||||
|
||||
// Enable SPI, Set as Master, Clock rate fck/16
|
||||
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
|
||||
// Slower SPI clock: SPR1=1, SPR0=1 = fosc/128
|
||||
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0) | (1 << CPHA);
|
||||
}
|
||||
|
||||
// Function to send 16-bit SPI frame
|
||||
void SPI_send_frame(uint8_t cs_pin, uint16_t address, uint16_t data) {
|
||||
debug_print("Sending SPI frame...\n");
|
||||
|
||||
// Construct 16-bit SDI frame
|
||||
// MSB format: Command Byte (8-bit)
|
||||
// [B15:B14] = 00 (standard frame)
|
||||
// [B13:B8] = Address (6 bits)
|
||||
// [B7:B0] = Write Command (W0 = 0)
|
||||
uint16_t command_byte = (0 << 14) | ((address & 0x3F) << 8) | (0 << 7);
|
||||
void SPI_write(uint8_t cs_pin, uint8_t addr, uint8_t data) {
|
||||
uint16_t frame = ((addr & 0x3F) << 8) | data;
|
||||
|
||||
// Full 16-bit frame
|
||||
uint16_t sdi_frame = command_byte | (data & 0xFF);
|
||||
|
||||
debug_print("Pulling CS low...\n");
|
||||
|
||||
delay_ms(50);
|
||||
|
||||
// Select the chip
|
||||
PORTC &= ~(1 << cs_pin);
|
||||
|
||||
// Delay to meet nSCS setup time
|
||||
_delay_us(0.05);
|
||||
|
||||
// Send high byte first (MSB)
|
||||
SPDR = (sdi_frame >> 8) & 0xFF;
|
||||
SPDR = frame >> 8;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
|
||||
// Send low byte
|
||||
SPDR = sdi_frame & 0xFF;
|
||||
SPDR = frame & 0xFF;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
|
||||
// Deselect the chip
|
||||
PORTC |= (1 << cs_pin);
|
||||
}
|
||||
|
||||
void SPI_read_frame(uint8_t cs_pin, uint16_t address) {
|
||||
|
||||
uint16_t *data;
|
||||
|
||||
// Construct 16-bit SDI frame
|
||||
// MSB format: Command Byte (8-bit)
|
||||
// [B15:B14] = 00 (standard frame)
|
||||
// [B13:B8] = Address (6 bits)
|
||||
// [B7:B0] = Read Command (R0 = 1)
|
||||
uint16_t command_byte = (0 << 14) | ((address & 0x3F) << 8) | (1 << 7);
|
||||
uint8_t SPI_read(uint8_t cs_pin, uint8_t addr) {
|
||||
uint16_t frame = (1 << 14) | ((addr & 0x3F) << 8);
|
||||
|
||||
// Full 16-bit frame
|
||||
uint16_t sdi_frame = command_byte;
|
||||
|
||||
// Select the chip
|
||||
PORTC &= ~(1 << cs_pin);
|
||||
_delay_us(1); // CS setup time
|
||||
|
||||
// Delay to meet nSCS setup time
|
||||
_delay_us(0.05);
|
||||
|
||||
// Send high byte first (MSB)
|
||||
SPDR = (sdi_frame >> 8) & 0xFF;
|
||||
SPDR = frame >> 8;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
|
||||
// Send low byte
|
||||
SPDR = sdi_frame & 0xFF;
|
||||
SPDR = frame & 0xFF;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
|
||||
// Read the data
|
||||
*data = SPDR;
|
||||
_delay_us(1); // Small delay before reading
|
||||
|
||||
// Deselect the chip
|
||||
SPDR = 0;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
uint8_t status = SPDR; // Status byte
|
||||
|
||||
SPDR = 0;
|
||||
while(!(SPSR & (1 << SPIF)));
|
||||
uint8_t data = SPDR; // Data byte
|
||||
|
||||
_delay_us(1); // CS hold time
|
||||
PORTC |= (1 << cs_pin);
|
||||
|
||||
char debug_msg[50];
|
||||
|
||||
debug_print("Data read from SPI frame...\n");
|
||||
debug_print("Data: ");
|
||||
sprintf(debug_msg, "0x%04X", *data);
|
||||
debug_print(debug_msg);
|
||||
debug_print("\n");
|
||||
|
||||
#ifdef DEBUG_SPI
|
||||
debug_print_read(addr, data);
|
||||
// Also print status for debugging
|
||||
serial_write('S'); serial_write('=');
|
||||
serial_write((status >> 4) < 10 ? ('0' + (status >> 4)) : ('A' + (status >> 4) - 10));
|
||||
serial_write((status & 0xF) < 10 ? ('0' + (status & 0xF)) : ('A' + (status & 0xF) - 10));
|
||||
serial_write(' ');
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void motor_spi_init() {
|
||||
if (MACHINE_TYPE == BAMBOO) {
|
||||
SPI_init();
|
||||
debug_print("Initializing SPI for stepper drivers...\n");
|
||||
|
||||
// Configure Chip Select pins as outputs
|
||||
DDRC |= (1 << CS1_PIN) | (1 << CS2_PIN);
|
||||
CS1_PORT |= (1 << CS1_PIN); // Set CS high (deselect)
|
||||
CS2_PORT |= (1 << CS2_PIN); // Set CS high (deselect)
|
||||
|
||||
// Send configuration to Driver 1
|
||||
SPI_send_frame(CS1_PIN, 0x04, 0x07);
|
||||
// Send configuration to Driver 2
|
||||
SPI_send_frame(CS2_PIN, 0x04, 0x07);
|
||||
|
||||
SPI_read_frame(CS1_PIN, 0x04);
|
||||
|
||||
debug_print("SPI initialization complete.\n");
|
||||
if (MACHINE_TYPE != BAMBOO) return;
|
||||
|
||||
_delay_ms(100);
|
||||
SPI_init();
|
||||
|
||||
for (uint8_t cs = CS1_PIN; cs <= CS2_PIN; cs++) {
|
||||
// Write configuration first
|
||||
SPI_write(cs, 0x04, 0xCF);
|
||||
_delay_ms(1);
|
||||
SPI_write(cs, 0x05, 0x06);
|
||||
_delay_ms(5); // Longer delay after write
|
||||
|
||||
// Then read back to verify
|
||||
SPI_read(cs, 0x04);
|
||||
SPI_read(cs, 0x05);
|
||||
}
|
||||
}
|
||||
Ładowanie…
Reference in New Issue