Skip to content

Commit

Permalink
new: Add suport to ESP32 LEDC (PWM output)
Browse files Browse the repository at this point in the history
  • Loading branch information
lcgamboa committed Oct 1, 2023
1 parent eb697b4 commit a59077c
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG_auto.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## (unreleased)

### New

* SD card support to CRC16 on write block and CRC7 on commands. [lcgamboa]

* SD card initial support to CRC16 on (ESP32 compatibility). [lcgamboa]

### Changes

* Draw the spare part before clicking in the window when a new part is added. [lcgamboa]
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ PACKAGE=picsimlab
MAINVER=0
MINORVER=9
VERSION=0.9.0
DATE=230924
DATE=231001
VERSION_STABLE=0.9.0
19 changes: 19 additions & 0 deletions src/boards/board_C3_DevKitC.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ cboard_C3_DevKitC::cboard_C3_DevKitC(void) {
master_uart[2].tx_pin = 0;
master_uart[2].rx_pin = 0;

bitbang_pwm_init(&ledc, this, 6);

if (PICSimLab.GetWindow()) {
// label1
label1 = new CLabel();
Expand Down Expand Up @@ -312,6 +314,7 @@ cboard_C3_DevKitC::~cboard_C3_DevKitC(void) {
wconfig->SetCanDestroy(true);
wconfig->WDestroy();
}
bitbang_pwm_end(&ledc);
}

// Reset board status
Expand Down Expand Up @@ -938,6 +941,19 @@ void cboard_C3_DevKitC::PinsExtraConfig(int cfg) {
master_uart[2].tx_pin = io2pin(gpio);
break;
*/
case 45: // ledc_ls_sig_out0
case 46: // ledc_ls_sig_out1
case 47: // ledc_ls_sig_out2
case 48: // ledc_ls_sig_out3
case 49: // ledc_ls_sig_out4
case 50: // ledc_ls_sig_out5
// printf("LEDC channel %i in GPIO %i\n", function - 45, gpio);
ledc.pins[function - 45] = io2pin(gpio);
break;
case 51: // rmt_sig_out0
case 52: // rmt_sig_out1
// printf("RMT channel %i in GPIO %i\n", function - 71, gpio);
break;
}

} break;
Expand Down Expand Up @@ -1029,6 +1045,9 @@ void cboard_C3_DevKitC::PinsExtraConfig(int cfg) {
}

} break;
case QEMU_EXTRA_PIN_LEDC_CFG:
bitbang_pwm_set_duty(&ledc, (cfg & 0x0F00) >> 8, cfg & 0xFF);
break;
}
}

Expand Down
55 changes: 45 additions & 10 deletions src/boards/board_DevKitC.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ cboard_DevKitC::cboard_DevKitC(void) {
master_uart[2].tx_pin = 0;
master_uart[2].rx_pin = 0;

bitbang_pwm_init(&ledc, this, 16);

if (PICSimLab.GetWindow()) {
// label1
label1 = new CLabel();
Expand Down Expand Up @@ -375,6 +377,7 @@ cboard_DevKitC::~cboard_DevKitC(void) {
wconfig->SetCanDestroy(true);
wconfig->WDestroy();
}
bitbang_pwm_end(&ledc);
}

// Reset board status
Expand All @@ -383,7 +386,7 @@ void cboard_DevKitC::Reset(void) {
if (qemu_started != 1) {
return;
}
uint32_t* strap_mode = qemu_picsimlab_get_internals(0);
uint32_t* strap_mode = qemu_picsimlab_get_internals(QEMU_INTERNAL_STRAP);

if (p_BOOT) {
*strap_mode = 0x12; // SPI_FAST_FLASH_BOOT
Expand Down Expand Up @@ -625,6 +628,8 @@ void cboard_DevKitC::Run_CPU_ns(uint64_t time) {

const float RNSTEP = 200.0 * pinc * inc_ns / TTIMEOUT;

MSetPin(IO0, p_BOOT);

for (uint64_t c = 0; c < time; c += inc_ns) {
if (ns_count < inc_ns) {
// reset pins mean value
Expand Down Expand Up @@ -709,7 +714,7 @@ void cboard_DevKitC::Run_CPU(void) {
}

if (!(status & CHR_TIOCM_CTS) && (status & CHR_TIOCM_DSR)) {
uint32_t* strap_mode = qemu_picsimlab_get_internals(0);
uint32_t* strap_mode = qemu_picsimlab_get_internals(QEMU_INTERNAL_STRAP);
*strap_mode = 0x0f; // UART_BOOT(UART0)
MReset(1);
}
Expand Down Expand Up @@ -848,8 +853,8 @@ void cboard_DevKitC::board_ButtonEvent(CControl* control, uint button, uint x, u

void cboard_DevKitC::PinsExtraConfig(int cfg) {
switch ((cfg & 0xf000) >> 12) {
case 1: {
uint32_t* gpio_in_sel = qemu_picsimlab_get_internals(1);
case QEMU_EXTRA_PIN_IN_CFG: {
uint32_t* gpio_in_sel = qemu_picsimlab_get_internals(QEMU_INTERNAL_GPIO_IN_SEL);
int function = cfg & 0x1ff;
int gpio = gpio_in_sel[cfg & 0x1ff] & 0x3F;
// printf("sel in %3i = %3i\n", gpio, function);
Expand Down Expand Up @@ -899,9 +904,8 @@ void cboard_DevKitC::PinsExtraConfig(int cfg) {
}

} break;
case 2: {
uint32_t* gpio_out_sel = qemu_picsimlab_get_internals(2);
// uint32_t* muxgpios = qemu_picsimlab_get_internals(3);
case QEMU_EXTRA_PIN_OUT_CFG: {
uint32_t* gpio_out_sel = qemu_picsimlab_get_internals(QEMU_INTERNAL_GPIO_OUT_SEL);

int function = gpio_out_sel[cfg & 0xff] & 0x1FF;
int gpio = cfg & 0xff;
Expand Down Expand Up @@ -976,7 +980,35 @@ void cboard_DevKitC::PinsExtraConfig(int cfg) {
master_spi[1].ctrl_on = 1;
master_spi[1].cs_pin[2] = io2pin(gpio);
break;

case 71: // ledc_hs_sig_out0
case 72: // ledc_hs_sig_out1
case 73: // ledc_hs_sig_out2
case 74: // ledc_hs_sig_out3
case 75: // ledc_hs_sig_out4
case 76: // ledc_hs_sig_out5
case 77: // ledc_hs_sig_out6
case 78: // ledc_hs_sig_out7
case 79: // ledc_ls_sig_out0
case 80: // ledc_ls_sig_out1
case 81: // ledc_ls_sig_out2
case 82: // ledc_ls_sig_out3
case 83: // ledc_ls_sig_out4
case 84: // ledc_ls_sig_out5
case 85: // ledc_ls_sig_out6
case 86: // ledc_ls_sig_out7
// printf("LEDC channel %i in GPIO %i\n", function - 71, gpio);
ledc.pins[function - 71] = io2pin(gpio);
break;
case 87: // rmt_sig_out0
case 88: // rmt_sig_out1
case 89: // rmt_sig_out2
case 90: // rmt_sig_out3
case 91: // rmt_sig_out4
case 92: // rmt_sig_out5
case 93: // rmt_sig_out6
case 94: // rmt_sig_out7
// printf("RMT channel %i in GPIO %i\n", function - 71, gpio);
break;
case 95: // I2CEXT1_SCL
master_i2c[1].ctrl_on = 1;
master_i2c[1].scl_pin = io2pin(gpio);
Expand All @@ -993,8 +1025,8 @@ void cboard_DevKitC::PinsExtraConfig(int cfg) {
}

} break;
case 4: {
uint32_t* muxgpios = qemu_picsimlab_get_internals(3);
case QEMU_EXTRA_PIN_IOMUX_CFG: {
uint32_t* muxgpios = qemu_picsimlab_get_internals(QEMU_INTERNAL_IOMUX_GPIOS);

int function = (muxgpios[cfg & 0xff] & 0x7000) >> 12;
int gpio = cfg & 0xff;
Expand Down Expand Up @@ -1078,6 +1110,9 @@ void cboard_DevKitC::PinsExtraConfig(int cfg) {
}

} break;
case QEMU_EXTRA_PIN_LEDC_CFG:
bitbang_pwm_set_duty(&ledc, (cfg & 0x0F00) >> 8, cfg & 0xFF);
break;
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/boards/bsim_qemu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@ void bsim_qemu::MReset(int flags) {
bitbang_uart_rst(&master_uart[0]);
bitbang_uart_rst(&master_uart[1]);
bitbang_uart_rst(&master_uart[2]);
bitbang_pwm_rst(&ledc);
}

const picpin* bsim_qemu::MGetPinsValues(void) {
Expand Down Expand Up @@ -1203,6 +1204,12 @@ void bsim_qemu::MStep(void) {
}
}
}
for (int i = 0; i < ledc.chanels; i++) {
if (ledc.pins[i]) {
pins[ledc.pins[i] - 1].dir = PD_OUT;
pins[ledc.pins[i] - 1].value = ledc.out[i];
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/boards/bsim_qemu.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define BOARD_QEMU_H

#include "../devices/bitbang_i2c.h"
#include "../devices/bitbang_pwm.h"
#include "../devices/bitbang_spi.h"
#include "../devices/bitbang_uart.h"
#include "../lib/board.h"
Expand Down Expand Up @@ -71,6 +72,7 @@ class bsim_qemu : virtual public board {
bitbang_i2c_t master_i2c[2];
bitbang_spi_t master_spi[2];
bitbang_uart_t master_uart[3];
bitbang_pwm_t ledc;
void IoLockAccess(void) override;
void IoUnlockAccess(void) override;
int GetUARTRX(const int uart_num) override;
Expand Down
90 changes: 90 additions & 0 deletions src/devices/bitbang_pwm.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* ########################################################################
PICSimLab - Programmable IC Simulator Laboratory
########################################################################
Copyright (c) : 2023-2023 Luis Claudio Gambôa Lopes <lcgamboa@yahoo.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
For e-mail suggestions : lcgamboa@yahoo.com
######################################################################## */

#include "bitbang_pwm.h"
#include "../lib/board.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define dprintf \
if (1) { \
} else \
printf

void bitbang_pwm_rst(bitbang_pwm_t* pwm) {
dprintf("bitbang_pwm rst\n");
pwm->counter = 0;
for (int i = 0; i < pwm->chanels; i++) {
pwm->duty[i] = 0;
pwm->out[i] = 0;
}
}

static void bitbang_pwm_ctrl_callback(void* arg) {
bitbang_pwm_t* pwm = (bitbang_pwm_t*)arg;
unsigned char out;

for (int i = 0; i < pwm->chanels; i++) {
if (pwm->pins[i]) {
if (pwm->counter < pwm->duty[i]) {
out = 1;
} else {
out = 0;
}
if (pwm->out[i] != out) {
pwm->out[i] = out;
ioupdated = 1;
}
}
}

pwm->counter++;
if (pwm->counter > 99) {
pwm->counter = 0;
}
}

void bitbang_pwm_init(bitbang_pwm_t* pwm, board* pboard, const unsigned char channels) {
dprintf("bitbang_pwm init\n");
pwm->chanels = channels;
bitbang_pwm_rst(pwm);
pwm->pboard = pboard;
pwm->TimerID = pwm->pboard->TimerRegister_us(2, bitbang_pwm_ctrl_callback, pwm);
pwm->pboard->TimerChange_us(pwm->TimerID, 2); // FIXME only 5kHz frequency
pwm->pboard->TimerSetState(pwm->TimerID, 0); // disabled
}

void bitbang_pwm_end(bitbang_pwm_t* pwm) {
dprintf("bitbang_pwm end\n");
pwm->pboard->TimerUnregister(pwm->TimerID);
}

void bitbang_pwm_set_duty(bitbang_pwm_t* pwm, const unsigned char channel, const char duty) {
dprintf("bitbang_pwm chanell %i (pin %i) set duty to %i%% \n", channel, pwm->pins[channel], duty);
pwm->pboard->TimerSetState(pwm->TimerID, 1);
pwm->duty[channel] = duty;
}
46 changes: 46 additions & 0 deletions src/devices/bitbang_pwm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* ########################################################################
PICSimLab - Programmable IC Simulator Laboratory
########################################################################
Copyright (c) : 2023-2023 Luis Claudio Gambôa Lopes <lcgamboa@yahoo.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
For e-mail suggestions : lcgamboa@yahoo.com
######################################################################## */

#ifndef BITBANG_PWM
#define BITBANG_PWM

class board;

typedef struct {
unsigned char chanels;
board* pboard;
int TimerID;
unsigned int counter;
unsigned char pins[32];
unsigned char out[32];
unsigned char duty[32];
} bitbang_pwm_t;

void bitbang_pwm_init(bitbang_pwm_t* pwm, board* pboard, const unsigned char channels = 8);
void bitbang_pwm_rst(bitbang_pwm_t* pwm);
void bitbang_pwm_end(bitbang_pwm_t* pwm);
void bitbang_pwm_set_duty(bitbang_pwm_t* pwm, const unsigned char channel, const char duty);

#endif // BITBANG_PWM

0 comments on commit a59077c

Please sign in to comment.