Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

[Решено]stm32 spi

Пн окт 16, 2017 16:40:09

Добрый день, форумчане.
Решил поиграться с дисплеем nokia 5510 и настроил передачу данных через dma, но возникла проблема с тем, что ножку CE отпускаю в прерывании дожидаясь флага BSY, но все равно рано, т.е. последний байт не успевает дойти до дисплея и пришлось вносить задержку. Послед задержки все работает. А как это правильно сделать? Чтобы без задержек?
На скрине с анализатора видно, что линия CE и DC подымаются раньше...
Спасибо.

Код:
void PCD8544_Init()
{
    RCC->AHBENR  |= RCC_AHBENR_DMA1EN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_SPI1EN | RCC_APB2ENR_AFIOEN;

    PCD8544_GPIO->CRL = (PCD8544_GPIO->CRL & ~(GPIO_CRL_CNF4 | GPIO_CRL_MODE4 | GPIO_CRL_CNF5 | GPIO_CRL_MODE5 |
                                       GPIO_CRL_CNF6 | GPIO_CRL_MODE6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE7)) |
                                      (GPIO_CRL_MODE4 | GPIO_CRL_MODE6 | GPIO_CRL_CNF5_1 | GPIO_CRL_CNF7_1 |
                                       GPIO_CRL_MODE5 | GPIO_CRL_MODE7);

    PCD8544_GPIO->CRH = (PCD8544_GPIO->CRH & ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_MODE10)) |
                        (GPIO_CRH_MODE9 | GPIO_CRH_MODE10);

    pin_set(PCD8544_DC | PCD8544_RST | PCD8544_CE);
    pin_reset(PCD8544_LIGHT);

    SPI1->CR1 |= SPI_CR1_BR_2 | SPI_CR1_CPHA | SPI_CR1_CPOL;
    SPI1->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM; // software NSS
    SPI1->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE;
    SPI1->CR2 |= SPI_CR2_TXDMAEN;

    DMA1_Channel3->CPAR  = (uint32_t)&SPI1->DR;
    DMA1_Channel3->CCR  |= DMA_CCR1_PL_1 | DMA_CCR1_MINC | DMA_CCR1_CIRC | DMA_CCR1_DIR |DMA_CCR1_TCIE;

    NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}


Код:
extern "C" void DMA1_Channel3_IRQHandler(void)
{
    if((DMA1->ISR & DMA_ISR_TCIF3) == DMA_ISR_TCIF3)
    {
        DMA1_Channel3->CCR &= ~DMA_CCR1_EN;
        DMA1->IFCR |= DMA_IFCR_CTCIF3;

        while((SPI1->SR & SPI_SR_BSY) != SPI_SR_BSY);

        pin_set(PCD8544_CE | PCD8544_DC);
    }
}


spi.png
(25.41 KiB) Скачиваний: 699
Последний раз редактировалось gruffi Пн окт 16, 2017 19:14:37, всего редактировалось 1 раз.

Re: stm32 spi

Пн окт 16, 2017 17:06:39

но возникла проблема с тем, что ножку CE отпускаю в прерывании дожидаясь флага BSY

Разве дожидаться нужно не сброса BSY?

Re: stm32 spi

Пн окт 16, 2017 17:07:20

что ножку CE отпускаю в прерывании дожидаясь флага BSY

When BSY is set, it indicates that a data transfer is in progress on the SPI

дождаться сброса флага, а не его взведения?

Re: stm32 spi

Пн окт 16, 2017 17:26:36

Спасибо, не дочитал. Сейчас все нормально отпускает вовремя. После очистки экрана он заливается черным цветом. Буду проверять настройки.

Код:
//----------
void PCD8544_Init()
{
    for(uint16_t i = 0; i < BUFFER_SIZE; i++)
    {
        PCD8544_Buffer[i] = 0x00;
    }

    uint8_t buffer[6] =
    {
        0x21,
        0xC8,
        0x06,
        0x13,
        0x20,
        0x0C
    };

    PCD8544_SendData(buffer, sizeof(buffer), TYPE_CMD);
}
//----------
void LCD_Clear()
{
    LCD_Goto(0, 0);

    uint8_t buffer[BUFFER_SIZE];

    for(uint16_t i = 0; i < BUFFER_SIZE; i++)
    {
        buffer[i] = 0x00;
    }

    PCD8544_SendData(buffer, BUFFER_SIZE, TYPE_DATA);

    LCD_Goto(0, 0);
}
//----------
void LCD_Goto(uint8_t y, uint8_t x)
{
    y |= 0x40;
    x |= 0x80;

    uint8_t buffer[2] =
    {
        x, y
    };

    PCD8544_SendData(buffer, 2, TYPE_CMD);
}
//----------
void PCD8544_SendData(const uint8_t* buffer, const uint16_t size, const type_t cmd)
{
    pin_reset(PCD8544_CE);

    if(cmd == TYPE_CMD)
    {
        pin_reset(PCD8544_DC);
    }
    else
    {
        pin_set(PCD8544_DC);
    }

    DMA1_Channel3->CMAR   = (uint32_t)buffer;
    DMA1_Channel3->CNDTR  = size;
    DMA1_Channel3->CCR   |= DMA_CCR1_EN;
}


Добавлено after 9 minutes:
Снова ошибся и был включен режим инверсии :). Спасибо.

Re: [РЕШЕНО]stm32 spi

Пт фев 09, 2018 13:21:25

Кто может подсказать про настройку и отправку данных по SPI на stm32f103. Хочу постепенно перейти от HAL на CMSIS. Через куб настроил SPI1, подключил к нему si4463, настроил и считываю с него информацию. Меняю функцию отправки на CMSIS
Код:
#define SPI1_DR_8bit          (*(__IO uint8_t *)((uint32_t)&(SPI1->DR)))

uint8_t si4463_spiByte(uint8_t writeData)
{
//  uint8_t readData;
//   HAL_SPI_TransmitReceive(&hspi1, &writeData, &readData, 1, 100); //readData=SPI.transfer(writeData);
//   return readData;
   
   uint8_t readData;
   while((SPI1->SR & SPI_SR_TXE) == RESET){}
      SPI1_DR_8bit = writeData;
      
    while (!(SPI1->SR & SPI_SR_RXNE)){
       // wait till data is available in the DR register
    }      
        readData = SPI1_DR_8bit;
      
   return readData;
}

И данная функция не работает.. Но если в кубе настроить SPI2, то данная функция отлично работает! Почему так? Читал что SPI1 и I2C1 вместе не работает там даже в ERRATE, по моему так называется документ, об этом написано. Но у мня кроме SPI ничего не включено. Вся настройка от куба, только отправка на CMSIS. Подскажите, что может быть?
Ответить