Machine à état SPI non bloquante fonctionnnelle en lecture
This commit is contained in:
parent
f1221027cc
commit
969755f889
@ -6,12 +6,13 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
add_executable(test
|
add_executable(test
|
||||||
test.c
|
test.c
|
||||||
|
spi_nb.c
|
||||||
gyro.c
|
gyro.c
|
||||||
)
|
)
|
||||||
pico_enable_stdio_usb(test 1)
|
pico_enable_stdio_usb(test 1)
|
||||||
pico_enable_stdio_uart(test 1)
|
pico_enable_stdio_uart(test 1)
|
||||||
pico_add_extra_outputs(test)
|
pico_add_extra_outputs(test)
|
||||||
target_link_libraries(test pico_stdlib hardware_spi hardware_i2c)
|
target_link_libraries(test pico_stdlib hardware_spi hardware_structs)
|
||||||
|
|
||||||
add_custom_target(Flash
|
add_custom_target(Flash
|
||||||
DEPENDS test
|
DEPENDS test
|
||||||
|
34
gyro.c
34
gyro.c
@ -2,6 +2,8 @@
|
|||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
#include "hardware/spi.h"
|
#include "hardware/spi.h"
|
||||||
|
#include "hardware/structs/spi.h"
|
||||||
|
#include "spi_nb.h"
|
||||||
|
|
||||||
const uint PIN_CS = 1;
|
const uint PIN_CS = 1;
|
||||||
|
|
||||||
@ -27,6 +29,22 @@ void Gyro_Init(void){
|
|||||||
//Ça doit être les valeurs par défaut, mais ça marche !
|
//Ça doit être les valeurs par défaut, mais ça marche !
|
||||||
spi_set_format(spi0, 8, SPI_CPHA_1, SPI_CPOL_1, SPI_MSB_FIRST);
|
spi_set_format(spi0, 8, SPI_CPHA_1, SPI_CPOL_1, SPI_MSB_FIRST);
|
||||||
|
|
||||||
|
// Pour chaque SPI nous avons les registres suivants :
|
||||||
|
|
||||||
|
// SSPCR0 : Configuré par spi_init()
|
||||||
|
// SSPCR1 : Configuré par spi_init()
|
||||||
|
// SSPDR : Lecture ou écriture des données (avec FIFO)
|
||||||
|
// SSPSR : C'est les status qui permettent de savoir si on a des données à recevoir ou à envoyer.
|
||||||
|
// SSPCPSR : Configuré par spi_init() ou baudrate
|
||||||
|
// SSPIMSC : Activation ou désactivation des interruptions
|
||||||
|
// SSPRIS : Etat des drapeaux des interrutions - sans tenir compte des masquages
|
||||||
|
// SSPMIS : Etat des drapeaux des interrutions - en tenant compte des masquages
|
||||||
|
// SSPICR : Pour effacer les interruptions
|
||||||
|
// SSPDMACR : DMA
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Test de la présence du gyroscope :
|
// Test de la présence du gyroscope :
|
||||||
if(gyro_init_check()){
|
if(gyro_init_check()){
|
||||||
puts("Gyroscope non trouve");
|
puts("Gyroscope non trouve");
|
||||||
@ -66,20 +84,12 @@ void Gyro_Read(void){
|
|||||||
int nb_recu;
|
int nb_recu;
|
||||||
// Lire l'adresse d'identification
|
// Lire l'adresse d'identification
|
||||||
// WHO_AM_I : 0x0F
|
// WHO_AM_I : 0x0F
|
||||||
|
puts("Lecture 0x0F");
|
||||||
cs_select();
|
cs_select();
|
||||||
puts("Envoi");
|
while(spi_nb_read_register_8bits(spi0, 0x0F, tampon, 1) == SPI_IN_PROGRESS);
|
||||||
|
|
||||||
spi_write_blocking(spi0, reg, 1);
|
|
||||||
// Doit répondre : 0b1101 0111
|
|
||||||
puts(reg);
|
|
||||||
puts("Lecture");
|
|
||||||
sleep_ms(10);
|
|
||||||
|
|
||||||
nb_recu = spi_read_blocking(spi0, 0x55, tampon, 1);
|
|
||||||
tampon[nb_recu]='\0';
|
|
||||||
puts(tampon);
|
|
||||||
cs_deselect();
|
cs_deselect();
|
||||||
|
tampon[1]='\0';
|
||||||
|
puts(tampon);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
173
spi_nb.c
Normal file
173
spi_nb.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "spi_nb.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/structs/spi.h"
|
||||||
|
#include "hardware/spi.h"
|
||||||
|
#include "hardware/regs/dreq.h"
|
||||||
|
|
||||||
|
#define SPI_ERR_TRANSMIT_FIFO_FULL 1
|
||||||
|
#define SPI_OK 0
|
||||||
|
#define SPI_BUSY 1
|
||||||
|
#define SPI_IDLE 0
|
||||||
|
|
||||||
|
|
||||||
|
#define PIN_CS 1
|
||||||
|
|
||||||
|
|
||||||
|
static inline void cs_select() {
|
||||||
|
asm volatile("nop \n nop \n nop");
|
||||||
|
gpio_put(PIN_CS, 0); // Active low
|
||||||
|
asm volatile("nop \n nop \n nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cs_deselect() {
|
||||||
|
asm volatile("nop \n nop \n nop");
|
||||||
|
gpio_put(PIN_CS, 1);
|
||||||
|
asm volatile("nop \n nop \n nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_nb_read_register_8bits(spi_inst_t * spi, uint16_t spi_slave_register, uint8_t *buffer, uint8_t nb_data_to_read){
|
||||||
|
uint16_t dummy_buffer[8]={0, 0, 0, 0,0, 0, 0, 0};
|
||||||
|
uint8_t nb_data_read;
|
||||||
|
static enum {
|
||||||
|
INIT,
|
||||||
|
WAIT_SPI_IDLE,
|
||||||
|
SEND_REGISTER_ADRESS,
|
||||||
|
WAIT_SENDING_DATA,
|
||||||
|
SEND_DUMMY_DATA,
|
||||||
|
WAIT_RECIEVING_DATA,
|
||||||
|
READ_DATA,
|
||||||
|
|
||||||
|
SPI_IN_ERROR,
|
||||||
|
}status=INIT;
|
||||||
|
|
||||||
|
switch(status){
|
||||||
|
case INIT:
|
||||||
|
cs_select();
|
||||||
|
case WAIT_SPI_IDLE:
|
||||||
|
if(spi_nb_busy(spi) == SPI_IDLE){
|
||||||
|
status = SEND_REGISTER_ADRESS;
|
||||||
|
puts("SEND_REGISTER_ADRESS");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEND_REGISTER_ADRESS:
|
||||||
|
spi_slave_register = spi_slave_register | 0x80 | 0X40;
|
||||||
|
if(spi_nb_write_data(spi, &spi_slave_register, 1) == SPI_OK){
|
||||||
|
status = WAIT_SENDING_DATA;
|
||||||
|
puts("WAIT_SENDING_DATA");
|
||||||
|
}else{
|
||||||
|
status = SPI_IN_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_SENDING_DATA:
|
||||||
|
if(!spi_nb_busy(spi)){
|
||||||
|
spi_nb_flush_recieve_fifo(spi);
|
||||||
|
status = SEND_DUMMY_DATA;
|
||||||
|
puts("SEND_DUMMY_DATA");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEND_DUMMY_DATA:
|
||||||
|
if(spi_nb_write_data(spi, dummy_buffer, nb_data_to_read) == SPI_OK){
|
||||||
|
status = WAIT_RECIEVING_DATA;
|
||||||
|
puts("WAIT_RECIEVING_DATA");
|
||||||
|
}else{
|
||||||
|
status = SPI_IN_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_RECIEVING_DATA:
|
||||||
|
if(!spi_nb_busy(spi)){
|
||||||
|
status = READ_DATA;
|
||||||
|
puts("READ_DATA");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_DATA:
|
||||||
|
cs_deselect();
|
||||||
|
nb_data_read = spi_nb_read_data_8bits(spi, buffer);
|
||||||
|
if(nb_data_read == nb_data_to_read){
|
||||||
|
puts("SPI_SUCCESS");
|
||||||
|
status = INIT;
|
||||||
|
return SPI_SUCCESS;
|
||||||
|
}
|
||||||
|
puts("SPI_FAILED");
|
||||||
|
status = SPI_IN_ERROR;
|
||||||
|
return SPI_FAILED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPI_IN_ERROR:
|
||||||
|
puts("SPI_IN_ERROR");
|
||||||
|
spi_nb_flush_recieve_fifo(spi);
|
||||||
|
cs_deselect();
|
||||||
|
status = INIT;
|
||||||
|
return SPI_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SPI_IN_PROGRESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Tell if the SPI is busy
|
||||||
|
/// @param spi SPI device to use (spi0 or spi1)
|
||||||
|
/// @return SPI_BUSY of SPI_IDLE
|
||||||
|
int spi_nb_busy(spi_inst_t * spi){
|
||||||
|
return (spi_get_hw(spi)->sr & SPI_SSPSR_BSY_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Empty SPI Recieve FIFO
|
||||||
|
/// @param spi SPI device to use (spi0 or spi1)
|
||||||
|
void spi_nb_flush_recieve_fifo(spi_inst_t * spi){
|
||||||
|
uint16_t dummy;
|
||||||
|
while(spi_get_hw(spi)->sr & SPI_SSPSR_RNE_BITS){
|
||||||
|
dummy = spi_get_hw(spi)->dr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief read the SPI Recieve FIFO
|
||||||
|
/// @param spi SPI device to use (spi0 or spi1)
|
||||||
|
/// @param buffer To store data recieved
|
||||||
|
/// @return Number of byte read
|
||||||
|
uint8_t spi_nb_read_data_8bits(spi_inst_t * spi, uint8_t * buffer){
|
||||||
|
uint8_t index = 0;
|
||||||
|
char debug[2]="x";
|
||||||
|
while(spi_get_hw(spi)->sr & SPI_SSPSR_RNE_BITS){
|
||||||
|
buffer[index] = (uint8_t)spi_get_hw(spi)->dr & SPI_SSPDR_DATA_BITS;
|
||||||
|
debug[0] = buffer[index];
|
||||||
|
puts(debug);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Write severals byte to the SPI Transmit FIFO
|
||||||
|
/// @param spi SPI device to use (spi0 or spi1)
|
||||||
|
/// @param buffer data to transmit
|
||||||
|
/// @param size size of the data to transmit
|
||||||
|
/// @return SPI_OK or SPI_ERR_TRANSMIT_FIFO_FULL
|
||||||
|
inline int spi_nb_write_data(spi_inst_t * spi, uint16_t * buffer, uint8_t size){
|
||||||
|
int statu_spi = SPI_OK;
|
||||||
|
uint8_t index=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
statu_spi = spi_nb_write_byte(spi, buffer[index]);
|
||||||
|
index++;
|
||||||
|
} while ( (statu_spi == SPI_OK) && (index < size));
|
||||||
|
return statu_spi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Write one "byte", 4 to 16 bits to the SPI Transmit FIFO.
|
||||||
|
/// @param spi
|
||||||
|
/// @param data : Data to send
|
||||||
|
/// @return SPI_OK if Ok, SPI_ERR_TRANSMIT_FIFO_FULL if fifo is full
|
||||||
|
int spi_nb_write_byte(spi_inst_t * spi, uint16_t data){
|
||||||
|
if(spi_get_hw(spi)->sr & SPI_SSPSR_TNF_BITS){
|
||||||
|
spi_get_hw(spi)->dr = data;
|
||||||
|
return SPI_OK;
|
||||||
|
}
|
||||||
|
return SPI_ERR_TRANSMIT_FIFO_FULL;
|
||||||
|
}
|
12
spi_nb.h
Normal file
12
spi_nb.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "hardware/spi.h"
|
||||||
|
|
||||||
|
#define SPI_SUCCESS 0
|
||||||
|
#define SPI_IN_PROGRESS 1
|
||||||
|
#define SPI_FAILED 2
|
||||||
|
|
||||||
|
int spi_nb_busy(spi_inst_t * spi);
|
||||||
|
void spi_nb_flush_recieve_fifo(spi_inst_t * spi);
|
||||||
|
int spi_nb_write_byte(spi_inst_t * spi, uint16_t data);
|
||||||
|
int spi_nb_write_data(spi_inst_t * spi, uint16_t * buffer, uint8_t size);
|
||||||
|
uint8_t spi_nb_read_data_8bits(spi_inst_t * spi, uint8_t * buffer);
|
||||||
|
int spi_nb_read_register_8bits(spi_inst_t * spi, uint16_t spi_slave_register, uint8_t *buffer, uint8_t nb_data_to_read);
|
2
test.c
2
test.c
@ -1,7 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
#include "hardware/i2c.h"
|
|
||||||
#include "pico/binary_info.h"
|
#include "pico/binary_info.h"
|
||||||
|
|
||||||
#include "gyro.h"
|
#include "gyro.h"
|
||||||
@ -18,6 +17,7 @@ int main() {
|
|||||||
gpio_set_dir(LED_PIN, GPIO_OUT);
|
gpio_set_dir(LED_PIN, GPIO_OUT);
|
||||||
gpio_put(LED_PIN, 1);
|
gpio_put(LED_PIN, 1);
|
||||||
|
|
||||||
|
sleep_ms(3000);
|
||||||
|
|
||||||
Gyro_Init();
|
Gyro_Init();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user