Comencé a ser programador de software y tengo experiencia profesional con grandes proyectos de software en c ++ y QT. Ahora cambié de compañía y también tengo que escribir un código de hardware de bajo nivel y tengo algunos problemas iniciales, jugando con los tonos de las hojas de datos. Soy nuevo en la programación de hardware en general y no sé mucho sobre herramientas o cómo puedo ayudarme a mí mismo.
Mi plan es comenzar la comunicación con un Sam4s16c (en un SAM4SXplained board ) a a L6470 motor a través de SPI. Mi problema es que la configuración de SPI me da dolor de cabeza y no funcionará. Al medir el CS / SS (pin31A), un osciloscopio solo mostrará alto voltaje (~ 3,2 V) pero no un reloj válido (debería ver un "arriba y abajo" aquí, o no?).
No estoy seguro de cuál es un buen valor para el divisor de velocidad en baudios (y qué significa en general) Después de mucho leer, escuché que tengo que "configurar" los pines correctamente, probé esto con estas líneas
gpio_configure_pin(SPI_NPCS1_PA31_GPIO, SPI_NPCS1_PA31_FLAGS);
gpio_set_pin_high(SPI_NPCS1_PA31_GPIO);
Mi código hasta ahora.
#include "asf.h"
#include "stdio_serial.h"
#include "conf_board.h"
#include "conf_clock.h"
#include "conf_spi_example.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Chip select. */
#define SPI_CHIP_SEL 0
#define SPI_CHIP_PCS spi_get_pcs(SPI_CHIP_SEL)
/* Clock polarity. */
#define SPI_CLK_POLARITY 1
/* Clock phase. */
#define SPI_CLK_PHASE 1
/* Delay before SPCK. */
//#define SPI_DLYBS 0x40
#define SPI_DLYBS 0xFF
/* Delay between consecutive transfers. */
#define SPI_DLYBCT 0x10
/* SPI clock setting (Hz). */
static uint32_t gs_ul_spi_clock = 1000000;
volatile uint32_t g_ul_ms_ticks = 0;
void SysTick_Handler(void)
{
g_ul_ms_ticks++;
}
static void mdelay(uint32_t ul_dly_ticks)
{
uint32_t ul_cur_ticks;
ul_cur_ticks = g_ul_ms_ticks;
while ((g_ul_ms_ticks - ul_cur_ticks) < ul_dly_ticks);
}
/**
* \brief Initialize SPI as master.
*/
static void spi_master_initialize(void)
{
//Assign I/O lines to peripheral
#define SPI_MISO_IOPIN IOPORT_CREATE_PIN(PIOA, PIO_PA12_IDX)
#define SPI_MOSI_IOPIN IOPORT_CREATE_PIN(PIOA, PIO_PA13_IDX)
#define SPI_SPCK_IOPIN IOPORT_CREATE_PIN(PIOA, PIO_PA14_IDX)
#define SPI_NPCS1_IOPIN IOPORT_CREATE_PIN(PIOA, PIO_PA31_IDX)
ioport_set_pin_mode(SPI_MISO_IOPIN, PIO_PERIPH_A);
ioport_disable_pin(SPI_MISO_IOPIN);
ioport_set_pin_mode(SPI_MOSI_IOPIN, PIO_PERIPH_A);
ioport_disable_pin(SPI_MOSI_IOPIN);
ioport_set_pin_mode(SPI_SPCK_IOPIN, PIO_PERIPH_A);
ioport_disable_pin(SPI_SPCK_IOPIN);
ioport_set_pin_mode(SPI_NPCS1_IOPIN, PIO_PERIPH_A);
ioport_disable_pin(SPI_NPCS1_IOPIN);
/* Configure an SPI peripheral. */
spi_enable_clock(SPI_MASTER_BASE);
spi_disable(SPI_MASTER_BASE);
spi_reset(SPI_MASTER_BASE);
spi_set_lastxfer(SPI_MASTER_BASE);
spi_set_master_mode(SPI_MASTER_BASE);
spi_disable_mode_fault_detect(SPI_MASTER_BASE);
spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, spi_get_pcs(SPI_CHIP_PCS));
spi_set_fixed_peripheral_select(SPI_MASTER_BASE);
spi_set_delay_between_chip_select(SPI_MASTER_BASE, 0);
// Set the Chip Select register
spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT);
int16_t baudrate = spi_calc_baudrate_div(96000, sysclk_get_cpu_hz());
spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL, 8); //sysclk_get_cpu_hz() / gs_ul_spi_clock);
spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
//spi_configure_cs_behavior(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CS_RISE_NO_TX);
spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
spi_enable(SPI_MASTER_BASE);
mdelay(100);
}
static void spi_master_write(uint16_t value)
{
spi_write(SPI_MASTER_BASE, value, SPI_CHIP_SEL, 0);
while ((spi_read_status(SPI) & SPI_SR_RDRF) == 0);/* Wait transfer done. */
}
static spi_status_t spi_master_read(uint16_t* data)
{
uint8_t uc_pcs;
spi_status_t returnValue = spi_read(SPI_MASTER_BASE, data, &uc_pcs);
return returnValue;
}
static void ledHello(void)
{
for (int i=0; i < 6; ++i)
{
LED_Toggle(LED0_GPIO);
LED_Toggle(LED1_GPIO);
mdelay(150);
}
mdelay(150);
for (int i=0; i < 5; ++i)
{
LED_Toggle(LED0_GPIO);
mdelay(150);
}
for (int i=0; i < 5; ++i)
{
LED_Toggle(LED1_GPIO);
mdelay(150);
}
// Both LEDs stay permanent on
}
int main(void)
{
board_init();
sysclk_init();
NVIC_DisableIRQ(SPI_IRQn);
NVIC_ClearPendingIRQ(SPI_IRQn);
NVIC_SetPriority(SPI_IRQn, 0);
NVIC_EnableIRQ(SPI_IRQn);
// [main_step_systick_init]
if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) {
// Systick configuration error
while (1);
}
ledHello(); // Code here toggles leds on board
/* Configure SPI as master, set up SPI clock. */
spi_master_initialize();
// activate the SPI of the micro controller of the L6470 via SPI
spi_master_write(0x18); // SetParam(Config)
spi_master_write(0x16);
spi_master_write(0x10);
mdelay(100);
while (1) {
spi_master_write(0x38); // GetParam(Config)
static uint16_t data;
spi_master_read(data);
spi_master_read(data);
}
}
#ifdef __cplusplus
}
#endif
En este momento, trato de configurar el reloj / salida spi correctamente. ¿Me perdí algo?