今日も1日がんばるぞぃ!
— いぬにゃん (@inunyann) July 2, 2023
昨日の日記。ch32v003でも、いぬにゃん表示と、ロータリエンコーダ(Encoder mode)での速度変更出来たので満足です。twitterくんの制限でお返しできずにすみません!リプも出来ませんでした…今日も引っかかるかもしれません…が、今週もよろしくお願い致します! pic.twitter.com/EL7VG18AyA
void Adafruit_NeoPixel::show(void) {
if (!pixels) return;
while (!canShow());
uint8_t *ptr, *end, p, bitMask;
uint16_t pinMask;
ptr = pixels;
end = ptr + numBytes;
p = *ptr++;
bitMask = 0x80;
GPIO_TypeDef *GPIOx = digitalPinToPort(pin);
pinMask = digitalPinToBitMask(pin);
__disable_irq();
//#define SYSCLK_FREQ_48MHZ_HSx 1
#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
if (is800KHz) {
#endif
for (;;) {
if (p & bitMask) { // ONE
// High 600ns
GPIOx->BSHR = pinMask;
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); // 1nop = 41.7ns? @ 24MHz
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); // 1nop = 20.8ns? @ 48MHz
#endif
// Low 300ns
GPIOx->BCR = pinMask;
asm volatile ("");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
#endif
} else { // ZERO
// High 300ns
GPIOx->BSHR = pinMask;
asm volatile ("nop; nop; nop; nop; nop;");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop;");
#endif
// Low 600ns
GPIOx->BCR = pinMask;
asm volatile ("nop; nop; nop; nop; nop;");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
#endif
}
if (bitMask >>= 1) {
asm volatile ("nop; nop; nop; nop; nop;");
} else {
if (ptr >= end) break;
p = *ptr++;
bitMask = 0x80;
}
}
#if defined(NEO_KHZ400)
} else { // 400 KHz bitstream
// ToDo!
}
#endif
__enable_irq();
endTime = micros(); // Save EOD time for latch on next call
}
void analogWrite(uint8_t duty) { // PD0(8) or PD2(19), ch4:PC4(14)
TIM_SetCompare1(TIM1, duty); // ,4
}
void analogInit(uint16_t freq = 1000) { // PD0(8) or PD2(19), ch4:PC4(14)
SystemCoreClockUpdate();
uint32_t psc = SystemCoreClock / 256 / freq;
if (psc >> 16) psc = 0xffff;
else if (psc) psc--;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); // ,C
GPIO_InitTypeDef gpioD0;
gpioD0.GPIO_Pin = GPIO_Pin_0; // or 2, 4
gpioD0.GPIO_Speed = GPIO_Speed_2MHz;
gpioD0.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioD0); // ,C
TIM_TimeBaseInitTypeDef tim1;
tim1.TIM_Period = 255;
tim1.TIM_Prescaler = psc;
tim1.TIM_ClockDivision = TIM_CKD_DIV1;
tim1.TIM_CounterMode = TIM_CounterMode_Up;
tim1.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &tim1);
TIM_OCInitTypeDef oc1;
oc1.TIM_OCMode = TIM_OCMode_PWM1;
oc1.TIM_OutputState = TIM_OutputState_Disable; // or En, En
oc1.TIM_OutputNState = TIM_OutputNState_Enable; // or Dis, Dis
oc1.TIM_Pulse = 0;
oc1.TIM_OCPolarity = TIM_OCPolarity_High;
oc1.TIM_OCNPolarity = TIM_OCPolarity_High;
oc1.TIM_OCIdleState = TIM_OCIdleState_Reset;
oc1.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(TIM1, &oc1); // ,4
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable); // ,4
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
}
void analogStop() {
TIM_Cmd(TIM1, DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);
pinMode(PD0, INPUT_PULLUP); // or PD2, PC4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, DISABLE);
}
#define getEncoderCount() TIM_GetCounter(TIM2)
void encoderInit() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
pinMode(PD4, INPUT_PULLUP); // T2CH1 : PD4(1)
pinMode(PD3, INPUT_PULLUP); // T2CH2 : PD3(20)
TIM_TimeBaseInitTypeDef tim2;
tim2.TIM_Period = 0xffff;
tim2.TIM_Prescaler = 1;
tim2.TIM_ClockDivision = TIM_CKD_DIV1;
tim2.TIM_CounterMode = TIM_CounterMode_Up;
tim2.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &tim2);
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2, ENABLE);
}
void encoderStop() {
TIM_Cmd(TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
}
#define TOUCH_THRESHOLD 20
uint16_t MeasureTouch(int16_t pin) {
uint32_t starttime, endtime;
GPIO_TypeDef *GPIOx = digitalPinToPort(pin);
uint16_t pinMask = digitalPinToBitMask(pin);
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
GPIOx->CFGLR = 0x00000008 << 4 * digitalPinToPinName(pin);
GPIOx->BSHR = pinMask;
starttime = SysTick->CNT;
while (!(GPIOx->INDR & pinMask));
endtime = SysTick->CNT;
return (uint16_t)(endtime - starttime);
}
bool isTouched(int16_t pin) {
SystemCoreClockUpdate();
uint32_t clk = SystemCoreClock;
if (clk != 24000000) SetSysClockTo_24MHZ_HSI();
uint16_t touch = MeasureTouch(pin);
if (clk == 93750) SetSysClockTo_94KHz_HSI();
else if (clk == 750000) SetSysClockTo_750KHz_HSI();
else if (clk == 6000000) SetSysClockTo_6MHZ_HSI();
return touch > TOUCH_THRESHOLD ? true : false;
}
volatile uint16_t adcDmaData[4]; // 4 chs
void startAdcDma() {
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div128);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
DMA_InitTypeDef dma;
dma.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->RDATAR;
dma.DMA_MemoryBaseAddr = (uint32_t)&adcDmaData;
dma.DMA_DIR = DMA_DIR_PeripheralSRC;
dma.DMA_BufferSize = sizeof(adcDmaData) / sizeof(adcDmaData[0]);
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma.DMA_Mode = DMA_Mode_Circular;
dma.DMA_Priority = DMA_Priority_Medium;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &dma);
DMA_Cmd(DMA1_Channel1, ENABLE);
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_4; // PD2(A3), PD3(A4), PD6(A6), PD4(A7)
gpio.GPIO_Speed = GPIO_Speed_2MHz;
gpio.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOD, &gpio);
ADC_InitTypeDef adc;
adc.ADC_Mode = ADC_Mode_Independent;
adc.ADC_ScanConvMode = ENABLE;
adc.ADC_ContinuousConvMode = ENABLE;
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc.ADC_DataAlign = ADC_DataAlign_Right;
adc.ADC_NbrOfChannel = sizeof(adcDmaData) / sizeof(adcDmaData[0]);
ADC_Init(ADC1, &adc);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_241Cycles); // PD2(A3)
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_241Cycles); // PD3(A4)
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_241Cycles); // PD6(A6)
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_241Cycles); // PD4(A7)
//ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 5, ADC_SampleTime_241Cycles);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_Vcalint, 6, ADC_SampleTime_241Cycles);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void stopAdcDma() {
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
ADC_Cmd(ADC1, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
DMA_Cmd(DMA1_Channel1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE);
}