Author Topic: $0.11 PY32F002A: Cortex-M0+ MCU, actually a PY32F030! 32/4KB, 48MHz, PLL, DMA...  (Read 55690 times)

0 Members and 3 Guests are viewing this topic.

Offline client

  • Newbie
  • Posts: 8
  • Country: cn
Thank you for your reply, I will try it.
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 2004
  • Country: dk
« Last Edit: May 21, 2024, 06:32:22 pm by bingo600 »
 

Online DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 6047
  • Country: es
Does anyone know if the PY32Fxxx - Has 5v tolerant I/O pins ?
When MCU VCC = 3v3
No.
Datasheet states max. voltage on any given pin is VCC+0.3V.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: bingo600

Offline ThichXemHen

  • Newbie
  • Posts: 1
  • Country: vn
Have you tried this with the f003 yet? It has more flash and ram than the 02, and if can be overclocked is basically the f030 that's twice as cheap.
 

Online DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 6047
  • Country: es
And the 002 is the same as the 030 too :-//
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline John Celo

  • Contributor
  • Posts: 24
  • Country: lt
I managed to bitbang neopixels ws2812s in arm32 assembly for the 8pin PY32F002. (by carefully counting the used instructions cycles & timing @ 24mhz). And after fixing some silly mistakes it works.  (couldn't get the SPI with DMA working for it compared to it's larger 16pin siblings for some reason)

However, in future I'd like to be able to measure and see the generated low/high duty cycle timings exactly (to verify that my theoretical calculations match with generated signal in practice).

What do I need for this, oscilloscope? Or would signal analyzer suffice?
Siglent SDS804X is 500eur, too expensive for me at the moment. I can get an OWON VDS1022 for 50eur (is it usable or too shabby?)
(100mhz 16ch signal analyzer can be made from rp2040)

 

Offline prosper

  • Regular Contributor
  • *
  • Posts: 83
  • Country: ca
if you send me your code (or a bin file), i can take some measurements for you. I have an 002a (tssop20) wired up to a ws2812 on my desk right now (using the 'LL' SPI example from @IOSetting's template. SPI is IMHO a better option than bitbang on arm mcu's, because stuff like wait states won't be a problem, abd it ought to be more portable)

The tool you want is a logic analyzer. Even a cheap 'fx2 logic analyzer' should be able to do what you want. An oscilloscope will gitr done, too, but thats swatting a fly with a sledgehammer
« Last Edit: June 19, 2024, 01:09:46 am by prosper »
 

Online DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 6047
  • Country: es
$10 aliexpresz 24MHz 8ch logo analyzer  :-+
SPI DMA works just fine, probably you missed something, you must understand the hardware and read a lot.
Though it's pretty easy with LL library!

Code: [Select]
#include "py32f0xx.h"
#include "py32f0xx_ll_adc.h"
#include "py32f0xx_ll_bus.h"
#include "py32f0xx_ll_cortex.h"
#include "py32f0xx_ll_dma.h"
#include "py32f0xx_ll_exti.h"
#include "py32f0xx_ll_gpio.h"
#include "py32f0xx_ll_pwr.h"
#include "py32f0xx_ll_rcc.h"
#include "py32f0xx_ll_system.h"
#include "py32f0xx_ll_spi.h"
#include "py32f0xx_ll_tim.h"
#include "py32f0xx_ll_utils.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

uint8_t led_data[] = { };                                                   // LED buffer

const LL_DMA_InitTypeDef DMA_LED_Init = {                                   // DMA init struct
    .PeriphOrM2MSrcAddress = (uint32_t)&SPI1->DR,
    .MemoryOrM2MDstAddress = (uint32_t)led_data,
    .Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH,
    .Mode = LL_DMA_MODE_NORMAL,
    .PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT,
    .MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT,
    .PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE,
    .MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE,
    .NbData = sizeof(led_data),
    .Priority = LL_DMA_PRIORITY_HIGH,
};

const LL_SPI_InitTypeDef SPI_init = {                                       // SPI init struct
    .TransferDirection = LL_SPI_HALF_DUPLEX_TX,
    .Mode = LL_SPI_MODE_MASTER,
    .DataWidth = LL_SPI_DATAWIDTH_8BIT,
    .ClockPolarity = LL_SPI_POLARITY_LOW,
    .ClockPhase = LL_SPI_PHASE_1EDGE,
    .NSS = LL_SPI_NSS_SOFT,
    .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2,
    .BitOrder = LL_SPI_MSB_FIRST,
    .SlaveSpeedMode = LL_SPI_SLAVE_SPEED_FAST,
};

void init_(void){                                                                           // Init function
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA | LL_IOP_GRP1_PERIPH_GPIOB);           // Enable peripheral clocks
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG | LL_APB1_GRP2_PERIPH_SPI1);
                                                                                            // Configure GPIO
    LL_GPIO_Init(GPIOA, &(LL_GPIO_InitTypeDef){ LL_GPIO_PIN_1, LL_GPIO_MODE_ALTERNATE, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_PULL_NO, LL_GPIO_AF10_SPI1 });    // PA1 = MOSI
    LL_GPIO_Init(GPIOA, &(LL_GPIO_InitTypeDef){ LL_GPIO_PIN_2, LL_GPIO_MODE_ALTERNATE, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_PULL_NO, LL_GPIO_AF10_SPI1 });    // PA2 = SCK

    LL_SPI_Init(SPI1, (LL_SPI_InitTypeDef*)&SPI_init);                                      // Init and enable SPI
    LL_SPI_Enable(SPI1);

    LL_SYSCFG_SetDMARemap_CH1(LL_SYSCFG_DMA_MAP_SPI1_TX);                                   // Init DMA
    LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, (LL_DMA_InitTypeDef*)&DMA_LED_Init);
    LL_DMA_ClearFlag_GI1(DMA1);
    //NVIC_SetPriority(DMA1_Channel1_IRQn, 1);                                              // DMA IRQ
    //NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    //LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
}
 
void DMA1_Channel1_IRQHandler(void){                                                        // DMA ISR

}

void send_led_data(void){
    //LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)led_data);                  // Not required unless using different buffers
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, sizeof(led_data) );
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_SPI_EnableDMAReq_TX(SPI1);                                                           // Enable SPI TX DMA request, will start sending data inmediately
    while(!LL_DMA_IsActiveFlag_TC1(DMA1) && LL_SPI_IsActiveFlag_BSY(SPI1));                 // Wait until DMA and SPI are done
    LL_SPI_DisableDMAReq_TX(SPI1);                                                          // Disable DMA
    LL_DMA_ClearFlag_TC1(DMA1);
    LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
}

int main(void)
{
  init_();
  send_led_data();
  while(1);
}
« Last Edit: June 19, 2024, 03:12:36 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline John Celo

  • Contributor
  • Posts: 24
  • Country: lt
Yes, i had gotten DMA and other features work on 16pin version with no issues, but couldn't get it to work for 8pin version (probably my mistake) and I had time pressure to make a gift for my mom in time, so I knew that bigbanging is the most surefire way to make it work, since the chip is basically only used to drive the neopixels and no other interupts should be firing (maybe some HAL timer thing for delay once every 1ms?).

Either way, it all works great! Thanks for advice!

I'll order a spare rp2040 and turn it into a signal 16ch 100mhz analyzer, hopefully that will enable to analyze timings of various digital signals (to make sure code works exactly as I think it does)
 

Online DavidAlfaTopic starter

  • Super Contributor
  • ***
  • Posts: 6047
  • Country: es
Probably due wrong pins assigned in the option bits, or IOMUX not configured?
Try with PA1 and PA3, they aren't multiplexed and should work straight away.

Code: [Select]
    LL_GPIO_Init(GPIOA, &(LL_GPIO_InitTypeDef){ LL_GPIO_PIN_1, LL_GPIO_MODE_ALTERNATE, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_PULL_NO, LL_GPIO_AF0_SPI1 });    // PA1 = SCK
    LL_GPIO_Init(GPIOA, &(LL_GPIO_InitTypeDef){ LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_PULL_NO, LL_GPIO_AF10_SPI1 });    // PA3 = MOSI
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: John Celo


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf