File indexing completed on 2025-05-11 08:22:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #include <libcpu/am335x.h>
0041 #include <stdio.h>
0042 #include <bsp/gpio.h>
0043 #include <bsp/bbb-gpio.h>
0044 #include <bsp.h>
0045 #include <bsp/pwmss.h>
0046 #include <bsp/bbb-pwm.h>
0047 #include <bsp/beagleboneblack.h>
0048
0049
0050
0051
0052
0053 #if IS_AM335X
0054
0055
0056
0057
0058
0059
0060
0061
0062 static uint32_t select_pwm(BBB_PWMSS pwm_id)
0063 {
0064 uint32_t baseAddr=0;
0065
0066 if (pwm_id == BBB_PWMSS0) {
0067 baseAddr = AM335X_EPWM_0_REGS;
0068 } else if (pwm_id == BBB_PWMSS1) {
0069 baseAddr = AM335X_EPWM_1_REGS;
0070 } else if (pwm_id == BBB_PWMSS2) {
0071 baseAddr = AM335X_EPWM_2_REGS;
0072 } else {
0073 baseAddr = 0;
0074 }
0075 return baseAddr;
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static uint32_t select_pwmss(BBB_PWMSS pwmss_id)
0087 {
0088 uint32_t baseAddr=0;
0089
0090 if (pwmss_id == BBB_PWMSS0) {
0091 baseAddr = AM335X_PWMSS0_MMAP_ADDR;
0092 } else if (pwmss_id == BBB_PWMSS1) {
0093 baseAddr = AM335X_PWMSS1_MMAP_ADDR;
0094 } else if (pwmss_id == BBB_PWMSS2) {
0095 baseAddr = AM335X_PWMSS2_MMAP_ADDR;
0096 } else {
0097 baseAddr = 0;
0098 }
0099 return baseAddr;
0100 }
0101
0102 bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
0103 {
0104 bool is_valid = true;
0105
0106 if(pwm_id == BBB_PWMSS0) {
0107 if (pin_no == BBB_P9_21_0B) {
0108 REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_P9_21_MUX_PWM);
0109 } else if (pin_no == BBB_P9_22_0A) {
0110 REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_P9_22_MUX_PWM);
0111 } else if (pin_no == BBB_P9_29_0B) {
0112 REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_P9_29_MUX_PWM);
0113 } else if (pin_no == BBB_P9_31_0A) {
0114 REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_P9_31_MUX_PWM);
0115 } else {
0116 is_valid = false;
0117 }
0118
0119 } else if (pwm_id == BBB_PWMSS1) {
0120 if (pin_no == BBB_P8_34_1B) {
0121 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_P8_34_MUX_PWM);
0122 } else if (pin_no == BBB_P8_36_1A) {
0123 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_P8_36_MUX_PWM);
0124 } else if (pin_no == BBB_P9_14_1A) {
0125 REG(AM335X_PADCONF_BASE + AM335X_CONF_GPMC_A2) = BBB_MUXMODE(BBB_P9_14_MUX_PWM);
0126 } else if (pin_no == BBB_P9_16_1B) {
0127 REG(AM335X_PADCONF_BASE + AM335X_CONF_GPMC_A3) = BBB_MUXMODE(BBB_P9_16_MUX_PWM);
0128 } else {
0129 is_valid = false;
0130 }
0131 } else if (pwm_id == BBB_PWMSS2) {
0132 if (pin_no == BBB_P8_13_2B) {
0133 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_P8_13_MUX_PWM);
0134 } else if (pin_no == BBB_P8_19_2A) {
0135 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_P8_19_MUX_PWM);
0136 } else if (pin_no == BBB_P8_45_2A) {
0137 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_P8_45_MUX_PWM);
0138 } else if (pin_no == BBB_P8_46_2B) {
0139 REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_P8_46_MUX_PWM);
0140 } else {
0141 is_valid = false;
0142 }
0143 } else {
0144 is_valid = false;
0145 }
0146 return is_valid;
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 static bool pwmss_tbclk_enable(BBB_PWMSS instance)
0159 {
0160 uint32_t enable_bit;
0161 bool is_valid = true;
0162
0163 if (instance == BBB_PWMSS0) {
0164 enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
0165 } else if (instance == BBB_PWMSS1) {
0166 enable_bit = AM335X_PWMSS_CTRL_PWMSS1_TBCLKEN;
0167 } else if (instance == BBB_PWMSS2) {
0168 enable_bit = AM335X_PWMSS_CTRL_PWMSS2_TBCLKEN;
0169 } else {
0170 is_valid = false;
0171 }
0172
0173 if (is_valid)
0174 {
0175 REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
0176 }
0177
0178 return is_valid;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 static bool pwm_clock_enable(BBB_PWMSS pwm_id)
0191 {
0192 const bool id_is_valid = pwm_id < BBB_PWMSS_COUNT;
0193 bool status = true;
0194
0195 if (id_is_valid) {
0196 const uint32_t baseAddr = select_pwmss(pwm_id);
0197 REG(baseAddr + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
0198 } else {
0199 status = false;
0200 }
0201 return status;
0202 }
0203
0204 bool beagle_pwm_init(BBB_PWMSS pwmss_id)
0205 {
0206 const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
0207 bool status = true;
0208
0209 if(id_is_valid) {
0210 pwmss_module_clk_config(pwmss_id);
0211 pwm_clock_enable(pwmss_id);
0212 pwmss_tbclk_enable(pwmss_id);
0213 } else {
0214 status =false;
0215 }
0216 return status;
0217 }
0218
0219 int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
0220 {
0221 uint32_t baseAddr;
0222 int status = 1;
0223 float cycle = 0.0f,divisor = 0;
0224 unsigned int i,j;
0225 const float CLKDIV_div[] = {1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0};
0226 const float HSPCLKDIV_div[] = {1.0, 2.0, 4.0, 6.0, 8.0, 10.0,12.0, 14.0};
0227 int NearCLKDIV =7,NearHSPCLKDIV =7,NearTBPRD =0;
0228
0229 if (pwm_freq <= BBB_PWM_FREQ_THRESHOLD) {
0230 status =0;
0231 }
0232
0233 if (duty_a < 0.0f || duty_a > 100.0f || duty_b < 0.0f || duty_b > 100.0f) {
0234 status = 0;
0235 }
0236 duty_a /= 100.0f;
0237 duty_b /= 100.0f;
0238
0239
0240 cycle = 1000000000.0f / pwm_freq;
0241
0242
0243
0244 divisor = (cycle / 655350.0f);
0245 if (divisor > (128 * 14)) {
0246 return 0;
0247 }
0248 else {
0249 for (i=0;i<8;i++) {
0250 for(j=0 ; j<8; j++) {
0251 if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV]
0252 * HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > divisor)) {
0253 NearCLKDIV = i;
0254 NearHSPCLKDIV = j;
0255 }
0256 }
0257 }
0258
0259 baseAddr = select_pwm(pwm_id);
0260
0261 REG16(baseAddr + AM335X_EPWM_TBCTL) &= ~(AM335X_TBCTL_CLKDIV_MASK | AM335X_TBCTL_HSPCLKDIV_MASK);
0262 const uint16_t clkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
0263 (~AM335X_EPWM_TBCTL_CLKDIV));
0264 const uint16_t clkdiv_write = ((NearCLKDIV
0265 << AM335X_EPWM_TBCTL_CLKDIV_SHIFT) & AM335X_EPWM_TBCTL_CLKDIV);
0266 REG16(baseAddr + AM335X_EPWM_TBCTL) = clkdiv_clear | clkdiv_write;
0267 const uint16_t hspclkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
0268 (~AM335X_EPWM_TBCTL_HSPCLKDIV));
0269 const uint16_t hspclkdiv_write = ((NearHSPCLKDIV <<
0270 AM335X_EPWM_TBCTL_HSPCLKDIV_SHIFT) & AM335X_EPWM_TBCTL_HSPCLKDIV);
0271 REG16(baseAddr + AM335X_EPWM_TBCTL) = hspclkdiv_clear | hspclkdiv_write;
0272 NearTBPRD = (cycle / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
0273 const uint16_t shadow_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
0274 (~AM335X_EPWM_PRD_LOAD_SHADOW_MASK));
0275 const uint16_t shadow_disable = (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
0276 AM335X_EPWM_TBCTL_PRDLD_SHIFT) & AM335X_EPWM_PRD_LOAD_SHADOW_MASK);
0277 REG16(baseAddr + AM335X_EPWM_TBCTL) = shadow_mask | shadow_disable;
0278 const uint16_t counter_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
0279 (~AM335X_EPWM_COUNTER_MODE_MASK));
0280 const uint16_t counter_shift = (((unsigned int)AM335X_EPWM_COUNT_UP <<
0281 AM335X_TBCTL_CTRMODE_SHIFT) & AM335X_EPWM_COUNTER_MODE_MASK);
0282 REG16(baseAddr + AM335X_EPWM_TBCTL) = counter_mask | counter_shift;
0283
0284 REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * duty_b);
0285 REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * duty_a);
0286 REG16(baseAddr + AM335X_EPWM_TBPRD) = (unsigned short)NearTBPRD;
0287 REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
0288 }
0289 return status;
0290 }
0291
0292 bool beagle_pwm_enable(BBB_PWMSS pwmid)
0293 {
0294 const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
0295 bool status = true;
0296
0297 if (id_is_valid) {
0298 const uint32_t baseAddr = select_pwm(pwmid);
0299
0300 REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
0301
0302 REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
0303 REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
0304
0305 REG16(baseAddr + AM335X_EPWM_TBCTL) |= AM335X_TBCTL_FREERUN | AM335X_TBCTL_CTRMODE_UP;
0306 } else {
0307 status =false;
0308 }
0309 return status;
0310 }
0311
0312 bool beagle_pwm_disable(BBB_PWMSS pwmid)
0313 {
0314 const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
0315 bool status = true;
0316
0317 if (id_is_valid) {
0318 const uint32_t baseAddr = select_pwm(pwmid);
0319 REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
0320 REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
0321 REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
0322 REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
0323 } else {
0324 status = false;
0325 }
0326 return status;
0327 }
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 static int pwmss_tb_clock_check(unsigned int pwmss_id)
0340 {
0341 unsigned int reg_value;
0342
0343
0344 reg_value = REG(AM335X_CONTROL_MODULE + AM335X_PWMSS_CTRL);
0345 return (reg_value & (1 << pwmss_id));
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 static unsigned int pwmss_clock_en_status(unsigned int pwmid)
0357 {
0358 unsigned int status;
0359 const uint32_t baseAddr = select_pwmss(pwmid);
0360
0361 status = REG(baseAddr + AM335X_PWMSS_CLKSTATUS);
0362 status = status >> 8 & 0x1;
0363 return status;
0364 }
0365
0366 bool beagle_pwmss_is_running(unsigned int pwmss_id)
0367 {
0368 const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
0369 bool status=true;
0370
0371 if (id_is_valid) {
0372 status = pwmss_clock_en_status(pwmss_id);
0373 if(status){
0374 status = pwmss_tb_clock_check(pwmss_id);
0375 } else {
0376 status = false;
0377 }
0378 } else {
0379 status = false;
0380 }
0381 return status;
0382 }
0383
0384 #endif
0385
0386
0387 #if IS_DM3730
0388
0389
0390
0391
0392
0393 bool beagle_pwm_init(BBB_PWMSS pwmss_id)
0394 {
0395 return false;
0396 }
0397 bool beagle_pwm_disable(BBB_PWMSS pwmid)
0398 {
0399 return false;
0400 }
0401 bool beagle_pwm_enable(BBB_PWMSS pwmid)
0402 {
0403 return false;
0404 }
0405 int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
0406 {
0407 return -1;
0408 }
0409 bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
0410 {
0411 return false;
0412 }
0413 bool beagle_pwmss_is_running(unsigned int pwmss_id)
0414 {
0415 return false;
0416 }
0417 #endif