Короче есть старинные джойстики от sp1. Хочу читать их stmкой. Начитался реверс доков - короче это spi (ну и протокол свой поверх).
Для быстрой проверки не дохлый ли джойстик накачал библиотек разных для дуины и начал смотреть - ну как обычно ничего не завелось. И просидев 2 дня - я таки нашел какой-то пример с какой-то библиотекой из 2х строк - и вуаля джойстик ответил. В общем поигрался и начал перетаскивать это на стм. Естественно на г..нодуине - это всё написано было софтверно никакого аппаратного spi.
на stmке врубил spi1 и начал - но нихрена не выходит - и да.... это мой первый проект на стм - с целью обучения в общем
сам spi работает - делаю петлю miso и mosi вызываю HAL_SPI_TransmitReceive - всё гуд - что уходит то и приходит.
провозившись порядочно - решил портировать код с дуины - портировал, всё работает(ток задержки поправил - видимо стм слишком резвый ).
код порта:
Код:
extern uint32_t SystemCoreClock;
void DWT_Init(void)
{
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk))
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
uint32_t DWT_Get(void)
{
return DWT->CYCCNT;
}
static inline uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int32_t tp = DWT_Get() + us * (SystemCoreClock / 1000000);
while (DWT_Compare(tp)) ;
}
#define DAT_Pin_PORT GPIOB
#define DAT_Pin GPIO_PIN_14
#define CLK_Pin_PORT GPIOB
#define CLK_Pin GPIO_PIN_13
#define CMD_Pin_PORT GPIOB
#define CMD_Pin GPIO_PIN_12
uint8_t _shift(uint8_t _dataOut) // Does the actual shifting, both in and out simultaneously
{
GPIO_PinState _temp = 0;
uint8_t _dataIn = 0;
for (uint8_t _i = 0; _i <= 7; _i++)
{
if (_dataOut & (1 << _i))
HAL_GPIO_WritePin(CMD_Pin_PORT, CMD_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(CMD_Pin_PORT, CMD_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(CLK_Pin_PORT, CLK_Pin, GPIO_PIN_RESET);
DWT_Delay(30);
_temp = HAL_GPIO_ReadPin(DAT_Pin_PORT, DAT_Pin);
if (_temp == GPIO_PIN_SET)
{
_dataIn = _dataIn | (0x80 >> _i); // Shifts the read data into _dataIn
}
HAL_GPIO_WritePin(CLK_Pin_PORT, CLK_Pin, GPIO_PIN_SET);
DWT_Delay(30);
}
return _dataIn;
}
unsigned int read_gp()
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
_shift(0x01);
_shift(0x42);
_shift(0x00);
uint8_t _data1 = ~_shift(0xFF);
uint8_t _data2 = ~_shift(0xFF);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
unsigned int _dataOut = (_data2 << 8) | _data1;
return _dataOut;
}
Сама команда как вы уже догадались 0x01,0x42,0x00,0xff,0xff
при запихивании её в HAL_SPI_TransmitReceive - на выходе мусор
Теперь немного о протоколе(мой перевод кусков):
1)допустимая частота от 100kHz до 500kHz - я пробовал и ~230 и ~140 (делителями SPI и APB2) - болт
2)Нога частоты в высоком уровне до тех пор пока не будут передаваться байты. Она становится в низкий уровень для начала 8 циклов во время которых данные одновременно передаются и принимаются.
2)байты передаются как LSB (least significant bit) первым, таким образом биты слева(раньше во времени) младшие.
Как видно с картинки - все сигналы по дефолту высокие.(Лучше картинки нет у них сайт побился)
Attention - это в их терминологии chip select.
Теперь мои настройки SPI:
Код:
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi1.Init.FirstBit = SPI_FIRSTBIT_LSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
Короче что я менял: поставил SPI_POLARITY_HIGH, SPI_FIRSTBIT_LSB и подтяжку на GPIO_PIN_6.
Без подтяжки не работает ни на дуино.. нигде, в общем нужна тут подтяжка - благо в stm она внутренняя есть
Всё равно приходит мусор - хз что ещё делать - я в тонкостях стм ещё плаваю.
Как мне настроить spi так, чтобы его работа была аналогичной поведению кода софтверного порта (см выше) ?ПС
Осцилла у меня пока нет - это печально